[Xfce4-commits] <xfce4-panel:master> Add option to filter tasklist window by monitor (bug #5199).
Nick Schermer
noreply at xfce.org
Sat Dec 18 01:10:01 CET 2010
Updating branch refs/heads/master
to 7eb8d06e42bf0dcb9a0ce45b9457569397b712ba (commit)
from be632df549abec6630a25c024e83d4b3440b2b96 (commit)
commit 7eb8d06e42bf0dcb9a0ce45b9457569397b712ba
Author: Nick Schermer <nick at xfce.org>
Date: Fri Dec 17 23:06:25 2010 +0100
Add option to filter tasklist window by monitor (bug #5199).
plugins/tasklist/tasklist-dialog.glade | 13 ++
plugins/tasklist/tasklist-widget.c | 189 ++++++++++++++++++++++++++++++--
plugins/tasklist/tasklist.c | 2 +
3 files changed, 196 insertions(+), 8 deletions(-)
diff --git a/plugins/tasklist/tasklist-dialog.glade b/plugins/tasklist/tasklist-dialog.glade
index beb5953..86a2be0 100644
--- a/plugins/tasklist/tasklist-dialog.glade
+++ b/plugins/tasklist/tasklist-dialog.glade
@@ -280,6 +280,19 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="include-all-monitors">
+ <property name="label" translatable="yes">Show windows from all mo_nitors</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
</child>
</object>
diff --git a/plugins/tasklist/tasklist-widget.c b/plugins/tasklist/tasklist-widget.c
index 4b30903..dd36a4f 100644
--- a/plugins/tasklist/tasklist-widget.c
+++ b/plugins/tasklist/tasklist-widget.c
@@ -69,6 +69,14 @@
#define xfce_tasklist_get_panel_plugin(tasklist) gtk_widget_get_ancestor (GTK_WIDGET (tasklist), XFCE_TYPE_PANEL_PLUGIN)
#define xfce_tasklist_horizontal(tasklist) ((tasklist)->horizontal || (!(tasklist)->rotate_vertically && (tasklist)->show_labels))
+#define xfce_tasklist_filter_monitors(tasklist) (!(tasklist)->all_monitors && (tasklist)->monitor_geometry.width != -1)
+#define xfce_tasklist_geometry_set_invalid(tasklist) ((tasklist)->monitor_geometry.width = -1)
+#define xfce_tasklist_geometry_has_point(tasklist, x, y) ( \
+ (x) >= ((tasklist)->monitor_geometry.x) \
+ && (x) < ((tasklist)->monitor_geometry.x + (tasklist)->monitor_geometry.width) \
+ && (y) >= ((tasklist)->monitor_geometry.y) \
+ && (y) < ((tasklist)->monitor_geometry.y + (tasklist)->monitor_geometry.height))
+
enum
@@ -76,6 +84,7 @@ enum
PROP_0,
PROP_GROUPING,
PROP_INCLUDE_ALL_WORKSPACES,
+ PROP_INCLUDE_ALL_MONITORS,
PROP_FLAT_BUTTONS,
PROP_SWITCH_WORKSPACE_ON_UNMINIMIZE,
PROP_SHOW_LABELS,
@@ -100,6 +109,7 @@ struct _XfceTasklist
/* the screen of this tasklist */
WnckScreen *screen;
+ GdkScreen *gdk_screen;
/* window children in the tasklist */
GList *windows;
@@ -140,6 +150,11 @@ struct _XfceTasklist
/* if we rotate buttons in a vertical panel */
guint rotate_vertically : 1;
+ /* whether we only show windows that are in the geometry of
+ * the monitor the tasklist is on */
+ guint all_monitors : 1;
+ GdkRectangle monitor_geometry;
+
/* whether we show wireframes when hovering a button in
* the tasklist */
guint show_wireframes : 1;
@@ -238,6 +253,7 @@ static GType xfce_tasklist_child_type (GtkContainer *container);
static void xfce_tasklist_arrow_button_toggled (GtkWidget *button, XfceTasklist *tasklist);
static void xfce_tasklist_connect_screen (XfceTasklist *tasklist);
static void xfce_tasklist_disconnect_screen (XfceTasklist *tasklist);
+static void xfce_tasklist_gdk_screen_changed (GdkScreen *gdk_screen, XfceTasklist *tasklist);
static void xfce_tasklist_active_window_changed (WnckScreen *screen, WnckWindow *previous_window, XfceTasklist *tasklist);
static void xfce_tasklist_active_workspace_changed (WnckScreen *screen, WnckWorkspace *previous_workspace, XfceTasklist *tasklist);
static void xfce_tasklist_window_added (WnckScreen *screen, WnckWindow *window, XfceTasklist *tasklist);
@@ -245,6 +261,7 @@ static void xfce_tasklist_window_removed (WnckScreen *screen, WnckWindow *window
static void xfce_tasklist_viewports_changed (WnckScreen *screen, XfceTasklist *tasklist);
static void xfce_tasklist_skipped_windows_state_changed (WnckWindow *window, WnckWindowState changed_state, WnckWindowState new_state, XfceTasklist *tasklist);
static void xfce_tasklist_sort (XfceTasklist *tasklist);
+static void xfce_tasklist_update_monitor_geometry (XfceTasklist *tasklist);
static gboolean xfce_tasklist_update_icon_geometries (gpointer data);
static void xfce_tasklist_update_icon_geometries_destroyed (gpointer data);
@@ -269,6 +286,7 @@ static XfceTasklistChild *xfce_tasklist_group_button_new (WnckClassGroup *class_
/* potential public functions */
static void xfce_tasklist_set_include_all_workspaces (XfceTasklist *tasklist, gboolean all_workspaces);
+static void xfce_tasklist_set_include_all_monitors (XfceTasklist *tasklist, gboolean all_monitors);
static void xfce_tasklist_set_button_relief (XfceTasklist *tasklist, GtkReliefStyle button_relief);
static void xfce_tasklist_set_show_labels (XfceTasklist *tasklist, gboolean show_labels);
static void xfce_tasklist_set_show_only_minimized (XfceTasklist *tasklist, gboolean only_minimized);
@@ -328,6 +346,13 @@ xfce_tasklist_class_init (XfceTasklistClass *klass)
EXO_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
+ PROP_INCLUDE_ALL_MONITORS,
+ g_param_spec_boolean ("include-all-monitors",
+ NULL, NULL,
+ TRUE,
+ EXO_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
PROP_FLAT_BUTTONS,
g_param_spec_boolean ("flat-buttons",
NULL, NULL,
@@ -459,6 +484,8 @@ xfce_tasklist_init (XfceTasklist *tasklist)
tasklist->show_wireframes = FALSE;
tasklist->show_handle = TRUE;
tasklist->rotate_vertically = TRUE;
+ tasklist->all_monitors = TRUE;
+ xfce_tasklist_geometry_set_invalid (tasklist);
#ifdef GDK_WINDOWING_X11
tasklist->wireframe_window = 0;
#endif
@@ -507,6 +534,10 @@ xfce_tasklist_get_property (GObject *object,
g_value_set_boolean (value, tasklist->all_workspaces);
break;
+ case PROP_INCLUDE_ALL_MONITORS:
+ g_value_set_boolean (value, tasklist->all_monitors);
+ break;
+
case PROP_FLAT_BUTTONS:
g_value_set_boolean (value, !!(tasklist->button_relief == GTK_RELIEF_NONE));
break;
@@ -566,6 +597,10 @@ xfce_tasklist_set_property (GObject *object,
xfce_tasklist_set_include_all_workspaces (tasklist, g_value_get_boolean (value));
break;
+ case PROP_INCLUDE_ALL_MONITORS:
+ xfce_tasklist_set_include_all_monitors (tasklist, g_value_get_boolean (value));
+ break;
+
case PROP_FLAT_BUTTONS:
xfce_tasklist_set_button_relief (tasklist,
g_value_get_boolean (value) ?
@@ -1258,21 +1293,27 @@ xfce_tasklist_arrow_button_toggled (GtkWidget *button,
static void
xfce_tasklist_connect_screen (XfceTasklist *tasklist)
{
- GdkScreen *screen;
- GList *windows, *li;
+ GList *windows, *li;
panel_return_if_fail (XFCE_IS_TASKLIST (tasklist));
panel_return_if_fail (tasklist->screen == NULL);
+ panel_return_if_fail (tasklist->gdk_screen == NULL);
/* set the new screen */
- screen = gtk_widget_get_screen (GTK_WIDGET (tasklist));
- tasklist->screen = wnck_screen_get (gdk_screen_get_number (screen));
+ tasklist->gdk_screen = gtk_widget_get_screen (GTK_WIDGET (tasklist));
+ tasklist->screen = wnck_screen_get (gdk_screen_get_number (tasklist->gdk_screen));
/* add all existing windows on this screen */
windows = wnck_screen_get_windows (tasklist->screen);
for (li = windows; li != NULL; li = li->next)
xfce_tasklist_window_added (tasklist->screen, li->data, tasklist);
+ /* monitor gdk changes */
+ g_signal_connect (G_OBJECT (tasklist->gdk_screen), "monitors-changed",
+ G_CALLBACK (xfce_tasklist_gdk_screen_changed), tasklist);
+ g_signal_connect (G_OBJECT (tasklist->gdk_screen), "size-changed",
+ G_CALLBACK (xfce_tasklist_gdk_screen_changed), tasklist);
+
/* monitor screen changes */
g_signal_connect (G_OBJECT (tasklist->screen), "active-window-changed",
G_CALLBACK (xfce_tasklist_active_window_changed), tasklist);
@@ -1298,12 +1339,17 @@ xfce_tasklist_disconnect_screen (XfceTasklist *tasklist)
panel_return_if_fail (XFCE_IS_TASKLIST (tasklist));
panel_return_if_fail (WNCK_IS_SCREEN (tasklist->screen));
+ panel_return_if_fail (GDK_IS_SCREEN (tasklist->gdk_screen));
/* disconnect monitor signals */
n = g_signal_handlers_disconnect_matched (G_OBJECT (tasklist->screen),
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, tasklist);
panel_return_if_fail (n == 5);
+ /* disconnect geometry changed signals */
+ g_signal_handlers_disconnect_by_func (G_OBJECT (tasklist->gdk_screen),
+ G_CALLBACK (xfce_tasklist_gdk_screen_changed), tasklist);
+
/* delete all known class groups (and their buttons) */
g_hash_table_remove_all (tasklist->class_groups);
@@ -1331,6 +1377,28 @@ xfce_tasklist_disconnect_screen (XfceTasklist *tasklist)
panel_assert (tasklist->skipped_windows == NULL);
tasklist->screen = NULL;
+ tasklist->gdk_screen = NULL;
+}
+
+
+
+static void
+xfce_tasklist_gdk_screen_changed (GdkScreen *gdk_screen,
+ XfceTasklist *tasklist)
+{
+ panel_return_if_fail (XFCE_IS_TASKLIST (tasklist));
+ panel_return_if_fail (GDK_IS_SCREEN (gdk_screen));
+ panel_return_if_fail (tasklist->gdk_screen == gdk_screen);
+
+ if (!tasklist->all_monitors)
+ {
+ /* update the monitor geometry */
+ xfce_tasklist_update_monitor_geometry (tasklist);
+
+ /* update visibility of buttons */
+ xfce_tasklist_active_workspace_changed (tasklist->screen,
+ NULL, tasklist);
+ }
}
@@ -1552,7 +1620,7 @@ xfce_tasklist_window_removed (WnckScreen *screen,
panel_return_if_fail (WNCK_IS_WINDOW (window));
n = g_signal_handlers_disconnect_matched (G_OBJECT (window),
G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, child);
- panel_return_if_fail (n == 4);
+ panel_return_if_fail (n == 5);
/* destroy the button, this will free the child data in the
* container remove function */
@@ -1621,6 +1689,41 @@ xfce_tasklist_sort (XfceTasklist *tasklist)
+static void
+xfce_tasklist_update_monitor_geometry (XfceTasklist *tasklist)
+{
+ GdkScreen *screen;
+ gboolean geometry_set = FALSE;
+ GdkWindow *window;
+
+ panel_return_if_fail (XFCE_IS_TASKLIST (tasklist));
+
+ if (!tasklist->all_monitors)
+ {
+ screen = gtk_widget_get_screen (GTK_WIDGET (tasklist));
+ window = gtk_widget_get_window (GTK_WIDGET (tasklist));
+
+ if (G_LIKELY (screen != NULL
+ && window != NULL
+ && gdk_screen_get_n_monitors (screen) > 1))
+ {
+ /* set the monitor geometry */
+ gdk_screen_get_monitor_geometry (screen,
+ gdk_screen_get_monitor_at_window (screen, window),
+ &tasklist->monitor_geometry);
+
+ geometry_set = TRUE;
+ }
+ }
+
+ /* make sure we never poke the window geometry unneeded
+ * in the visibility function */
+ if (!geometry_set)
+ xfce_tasklist_geometry_set_invalid (tasklist);
+}
+
+
+
static gboolean
xfce_tasklist_update_icon_geometries (gpointer data)
{
@@ -1954,17 +2057,31 @@ static inline gboolean
xfce_tasklist_button_visible (XfceTasklistChild *child,
WnckWorkspace *active_ws)
{
+ XfceTasklist *tasklist = XFCE_TASKLIST (child->tasklist);
+ gint x, y, w, h;
+
panel_return_val_if_fail (active_ws == NULL || WNCK_IS_WORKSPACE (active_ws), FALSE);
- panel_return_val_if_fail (XFCE_IS_TASKLIST (child->tasklist), FALSE);
+ panel_return_val_if_fail (XFCE_IS_TASKLIST (tasklist), FALSE);
panel_return_val_if_fail (WNCK_IS_WINDOW (child->window), FALSE);
- if (child->tasklist->all_workspaces
+ if (xfce_tasklist_filter_monitors (tasklist))
+ {
+ /* center of the window must be on this screen */
+ wnck_window_get_geometry (child->window, &x, &y, &w, &h);
+ x += w / 2;
+ y += h / 2;
+
+ if (!xfce_tasklist_geometry_has_point (tasklist, x, y))
+ return FALSE;
+ }
+
+ if (tasklist->all_workspaces
|| (active_ws != NULL
&& (G_UNLIKELY (wnck_workspace_is_virtual (active_ws))
? wnck_window_is_in_viewport (child->window, active_ws)
: wnck_window_is_on_workspace (child->window, active_ws))))
{
- return (!child->tasklist->only_minimized
+ return (!tasklist->only_minimized
|| wnck_window_is_minimized (child->window));
}
@@ -2243,6 +2360,29 @@ xfce_tasklist_button_workspace_changed (WnckWindow *window,
+static void
+xfce_tasklist_button_geometry_changed2 (WnckWindow *window,
+ XfceTasklistChild *child)
+{
+ WnckWorkspace *active_ws;
+
+ panel_return_if_fail (child->window == window);
+ panel_return_if_fail (XFCE_IS_TASKLIST (child->tasklist));
+ panel_return_if_fail (WNCK_IS_SCREEN (child->tasklist->screen));
+
+ if (xfce_tasklist_filter_monitors (child->tasklist))
+ {
+ /* check if we need to change the visibility of the button */
+ active_ws = wnck_screen_get_active_workspace (child->tasklist->screen);
+ if (xfce_tasklist_button_visible (child, active_ws))
+ gtk_widget_show (child->button);
+ else
+ gtk_widget_hide (child->button);
+ }
+}
+
+
+
#ifdef GDK_WINDOWING_X11
static void
xfce_tasklist_button_geometry_changed (WnckWindow *window,
@@ -2630,6 +2770,8 @@ xfce_tasklist_button_new (WnckWindow *window,
G_CALLBACK (xfce_tasklist_button_state_changed), child);
g_signal_connect (G_OBJECT (window), "workspace-changed",
G_CALLBACK (xfce_tasklist_button_workspace_changed), child);
+ g_signal_connect (G_OBJECT (window), "geometry-changed",
+ G_CALLBACK (xfce_tasklist_button_geometry_changed2), child);
/* poke functions */
xfce_tasklist_button_icon_changed (window, child);
@@ -3214,6 +3356,37 @@ xfce_tasklist_set_include_all_workspaces (XfceTasklist *tasklist,
static void
+xfce_tasklist_set_include_all_monitors (XfceTasklist *tasklist,
+ gboolean all_monitors)
+{
+ panel_return_if_fail (XFCE_IS_TASKLIST (tasklist));
+
+ all_monitors = !!all_monitors;
+
+ if (tasklist->all_monitors != all_monitors)
+ {
+ tasklist->all_monitors = all_monitors;
+
+ /* set the geometry to invalid or update the geometry and
+ * update the visibility of the buttons */
+ if (all_monitors)
+ {
+ xfce_tasklist_geometry_set_invalid (tasklist);
+
+ /* update visibility of buttons */
+ xfce_tasklist_active_workspace_changed (tasklist->screen,
+ NULL, tasklist);
+ }
+ else if (tasklist->gdk_screen != NULL)
+ {
+ xfce_tasklist_gdk_screen_changed (tasklist->gdk_screen, tasklist);
+ }
+ }
+}
+
+
+
+static void
xfce_tasklist_set_button_relief (XfceTasklist *tasklist,
GtkReliefStyle button_relief)
{
diff --git a/plugins/tasklist/tasklist.c b/plugins/tasklist/tasklist.c
index d1c9031..0881224 100644
--- a/plugins/tasklist/tasklist.c
+++ b/plugins/tasklist/tasklist.c
@@ -126,6 +126,7 @@ tasklist_plugin_construct (XfcePanelPlugin *panel_plugin)
{ "show-labels", G_TYPE_BOOLEAN },
{ "grouping", G_TYPE_UINT },
{ "include-all-workspaces", G_TYPE_BOOLEAN },
+ { "include-all-monitors", G_TYPE_BOOLEAN },
{ "flat-buttons", G_TYPE_BOOLEAN },
{ "switch-workspace-on-unminimize", G_TYPE_BOOLEAN },
{ "show-only-minimized", G_TYPE_BOOLEAN },
@@ -211,6 +212,7 @@ tasklist_plugin_configure_plugin (XfcePanelPlugin *panel_plugin)
TASKLIST_DIALOG_BIND ("show-labels", "active")
TASKLIST_DIALOG_BIND ("grouping", "active")
TASKLIST_DIALOG_BIND ("include-all-workspaces", "active")
+ TASKLIST_DIALOG_BIND ("include-all-monitors", "active")
TASKLIST_DIALOG_BIND ("flat-buttons", "active")
TASKLIST_DIALOG_BIND ("rotate-vertically", "active")
TASKLIST_DIALOG_BIND_INV ("switch-workspace-on-unminimize", "active")
More information about the Xfce4-commits
mailing list