From 18ab53964e2dad952466e13e33cfa36892a49d97 Mon Sep 17 00:00:00 2001 From: Sebastian Geiger Date: Sun, 9 Dec 2018 17:16:56 +0100 Subject: [PATCH 1/2] windowpicker: fix item assignment on workarea change This fixes a long standing issue on multi-monitor setups. When a panel moves to another monitor then the assignment of task items to the task list needs to be recomputed. This patch fixes the issue by listening for changes of the workarea and reinitializes the task lists. --- configure.ac | 3 ++ windowpicker/src/Makefile.am | 2 + windowpicker/src/task-list.c | 93 ++++++++++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 358c4f49c..cf90abbd8 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,9 @@ fi AC_MSG_NOTICE([installing applets in $LIBPANEL_APPLET_DIR]) AC_SUBST(LIBPANEL_APPLET_DIR) +dnl -- check for X11 (required) ----------------------------------------------- +PKG_CHECK_MODULES([X11], [x11]) + dnl -- check for libgtop (optional) ------------------------------------------- build_gtop_applets=false PKG_CHECK_MODULES(GTOP_APPLETS, diff --git a/windowpicker/src/Makefile.am b/windowpicker/src/Makefile.am index 352e159c4..cb55229cd 100644 --- a/windowpicker/src/Makefile.am +++ b/windowpicker/src/Makefile.am @@ -13,6 +13,7 @@ libwindow_picker_applet_la_CFLAGS = \ -I$(top_srcdir) \ $(GNOME_APPLETS_CFLAGS) \ $(LIBWNCK_CFLAGS) \ + $(X11_CFLAGS) \ $(GCC_FLAGS) \ $(WARN_CFLAGS) \ $(AM_CFLAGS) \ @@ -27,6 +28,7 @@ libwindow_picker_applet_la_LDFLAGS = \ libwindow_picker_applet_la_LIBADD = \ $(GNOME_APPLETS_LIBS) \ $(LIBWNCK_LIBS) \ + $(X11_LIBS) \ $(LIBM) \ $(NULL) diff --git a/windowpicker/src/task-list.c b/windowpicker/src/task-list.c index 312f59c60..0836622a7 100644 --- a/windowpicker/src/task-list.c +++ b/windowpicker/src/task-list.c @@ -23,10 +23,12 @@ #include #include +#include struct _TaskListPrivate { WnckScreen *screen; WpApplet *windowPickerApplet; + guint size_update_event_source; }; G_DEFINE_TYPE_WITH_PRIVATE (TaskList, task_list, GTK_TYPE_BOX); @@ -61,11 +63,8 @@ static void on_task_item_closed ( TaskItem *item, TaskList *list) { - gtk_container_remove ( - GTK_CONTAINER (list), - GTK_WIDGET (item) - ); - gtk_widget_destroy (GTK_WIDGET (item)); + gtk_container_remove (GTK_CONTAINER (list), + GTK_WIDGET (item)); } static gint @@ -211,6 +210,82 @@ static void on_task_list_orient_changed(PanelApplet *applet, gtk_widget_queue_resize(GTK_WIDGET(box)); } +static void +remove_task_item (GtkWidget *item, + gpointer list) +{ + g_return_if_fail (TASK_IS_LIST (list)); + + gtk_container_remove (GTK_CONTAINER (list), item); +} + +static gboolean +on_monitors_changed (gpointer user_data) +{ + TaskList *list; + GdkWindow *window; + gint list_monitor; + + list = user_data; + window = gtk_widget_get_window (GTK_WIDGET (list)); + + list_monitor = gdk_screen_get_monitor_at_window (gdk_screen_get_default (), + window); + + if (task_list_get_monitor (list) == list_monitor) + gtk_container_foreach (GTK_CONTAINER (list), remove_task_item, list); + + GList *windows = wnck_screen_get_windows (list->priv->screen); + + while (windows != NULL) + { + on_window_opened (list->priv->screen, windows->data, list); + windows = windows->next; + } + + list->priv->size_update_event_source = 0; + + return G_SOURCE_REMOVE; +} + + +static GdkFilterReturn +window_filter_function (GdkXEvent *gdk_xevent, + GdkEvent *event, + gpointer user_data) +{ + TaskList *list = user_data; + + XEvent *xevent = (XEvent *) gdk_xevent; + + switch (xevent->type) + { + case PropertyNotify: + { + XPropertyEvent *propertyEvent; + + propertyEvent = (XPropertyEvent *) xevent; + + const Atom WORKAREA_ATOM = XInternAtom (propertyEvent->display, + "_NET_WORKAREA", True); + + if (propertyEvent->atom != WORKAREA_ATOM) + return GDK_FILTER_CONTINUE; + + if (list->priv->size_update_event_source != 0) + return GDK_FILTER_CONTINUE; + + list->priv->size_update_event_source = g_idle_add (on_monitors_changed, + user_data); + + break; + } + default:break; + } + + return GDK_FILTER_CONTINUE; +} + static void task_list_dispose (GObject *object) { @@ -229,6 +304,10 @@ task_list_finalize (GObject *object) task_lists = g_slist_remove (task_lists, taskList); + gdk_window_remove_filter (gtk_widget_get_window (GTK_WIDGET (taskList)), + window_filter_function, + taskList); + G_OBJECT_CLASS (task_list_parent_class)->finalize (object); } @@ -276,6 +355,10 @@ GtkWidget *task_list_new (WpApplet *windowPickerApplet) { g_signal_connect (taskList->priv->screen, "window-opened", G_CALLBACK (on_window_opened), taskList); + gdk_window_add_filter (gtk_widget_get_window (GTK_WIDGET (taskList)), + window_filter_function, + taskList); + GList *windows = wnck_screen_get_windows (taskList->priv->screen); while (windows != NULL) { on_window_opened (taskList->priv->screen, windows->data, taskList); -- GitLab From 6c452512ded9fda58c392a82a43c7e86ac4bf72c Mon Sep 17 00:00:00 2001 From: Sebastian Geiger Date: Fri, 14 Dec 2018 16:56:26 +0100 Subject: [PATCH 2/2] windowpicker: use GdkMonitor --- windowpicker/src/task-item.c | 26 +++++++++++----------- windowpicker/src/task-item.h | 8 ++++--- windowpicker/src/task-list.c | 42 ++++++++++++++++++------------------ windowpicker/src/task-list.h | 6 +++--- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/windowpicker/src/task-item.c b/windowpicker/src/task-item.c index 3bb52a2c3..1a3c1c58b 100644 --- a/windowpicker/src/task-item.c +++ b/windowpicker/src/task-item.c @@ -43,7 +43,7 @@ struct _TaskItemPrivate { GTimeVal urgent_time; guint blink_timer; gboolean mouse_over; - gint monitor; + GdkMonitor *monitor; WpApplet *windowPickerApplet; }; @@ -488,22 +488,23 @@ on_window_type_changed (WnckWindow *window, } } -static gint +static GdkMonitor * get_window_monitor (WnckWindow *window) { gint x; gint y; gint w; gint h; - gint window_monitor; - GdkScreen *gdk_screen; + GdkMonitor *window_monitor; + GdkDisplay *gdk_display; wnck_window_get_geometry (window, &x, &y, &w, &h); - gdk_screen = gdk_screen_get_default (); - window_monitor = gdk_screen_get_monitor_at_point (gdk_screen, - x + w / 2, - y + h / 2); + gdk_display = gdk_display_get_default (); + window_monitor = gdk_display_get_monitor_at_point (gdk_display, + x + w / 2, + y + h / 2); + return window_monitor; } @@ -511,8 +512,8 @@ static void on_window_geometry_changed (WnckWindow *window, TaskItem *item) { - gint old_monitor; - gint window_monitor; + GdkMonitor *old_monitor; + GdkMonitor *window_monitor; window_monitor = get_window_monitor (window); @@ -855,7 +856,7 @@ static void task_item_class_init (TaskItemClass *klass) { task_item_signals [TASK_ITEM_MONITOR_CHANGED] = g_signal_new ("monitor-changed", TASK_TYPE_ITEM, G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_INT); + 0, NULL, NULL, NULL, G_TYPE_NONE, 1, GDK_TYPE_MONITOR); } static void task_item_init (TaskItem *item) { @@ -967,7 +968,8 @@ GtkWidget *task_item_new (WpApplet* windowPickerApplet, WnckWindow *window) { return item; } -gint task_item_get_monitor (TaskItem *item) +GdkMonitor * +task_item_get_monitor (TaskItem *item) { return item->priv->monitor; } diff --git a/windowpicker/src/task-item.h b/windowpicker/src/task-item.h index 666513da8..513d292ee 100644 --- a/windowpicker/src/task-item.h +++ b/windowpicker/src/task-item.h @@ -48,9 +48,11 @@ struct _TaskItemClass { void (* itemclosed) (TaskItem *item); }; -GType task_item_get_type (void) G_GNUC_CONST; -GtkWidget * task_item_new (WpApplet *windowPickerApplet, WnckWindow *window); +GType task_item_get_type (void) G_GNUC_CONST; -gint task_item_get_monitor (TaskItem *item); +GtkWidget *task_item_new (WpApplet *windowPickerApplet, + WnckWindow *window); + +GdkMonitor *task_item_get_monitor (TaskItem *item); #endif /* _TASK_ITEM_H_ */ diff --git a/windowpicker/src/task-list.c b/windowpicker/src/task-list.c index 0836622a7..ed17f27e0 100644 --- a/windowpicker/src/task-list.c +++ b/windowpicker/src/task-list.c @@ -36,11 +36,11 @@ G_DEFINE_TYPE_WITH_PRIVATE (TaskList, task_list, GTK_TYPE_BOX); static GSList *task_lists; static TaskList * -get_task_list_for_monitor (TaskList *task_list, - gint monitor) +get_task_list_for_monitor (TaskList *task_list, + GdkMonitor *monitor) { GSList *list; - gint list_monitor; + GdkMonitor *list_monitor; list = task_lists; @@ -67,19 +67,19 @@ static void on_task_item_closed ( GTK_WIDGET (item)); } -static gint +static GdkMonitor * window_get_monitor (WnckWindow *window) { - GdkScreen *gdk_screen; + GdkDisplay *gdk_display; gint x, y, w, h; - gdk_screen = gdk_screen_get_default (); + gdk_display = gdk_display_get_default (); wnck_window_get_geometry (window, &x, &y, &w, &h); - return gdk_screen_get_monitor_at_point (gdk_screen, - x + w / 2, - y + h / 2); + return gdk_display_get_monitor_at_point (gdk_display, + x + w / 2, + y + h / 2); } static void @@ -87,8 +87,8 @@ on_task_item_monitor_changed_cb (TaskItem *item, gint old_monitor, TaskList *current_list) { - gint monitor; - gint list_monitor; + GdkMonitor *monitor; + GdkMonitor *list_monitor; TaskList *list; monitor = task_item_get_monitor (item); @@ -122,8 +122,8 @@ static void create_task_item (TaskList *taskList, WnckWindow *window) { GtkWidget *item; - gint list_monitor; - gint window_monitor; + GdkMonitor *list_monitor; + GdkMonitor *window_monitor; guint num; num = g_slist_length (task_lists); @@ -224,13 +224,13 @@ on_monitors_changed (gpointer user_data) { TaskList *list; GdkWindow *window; - gint list_monitor; + GdkMonitor *list_monitor; list = user_data; window = gtk_widget_get_window (GTK_WIDGET (list)); - list_monitor = gdk_screen_get_monitor_at_window (gdk_screen_get_default (), - window); + list_monitor = gdk_display_get_monitor_at_window (gdk_display_get_default (), + window); if (task_list_get_monitor (list) == list_monitor) gtk_container_foreach (GTK_CONTAINER (list), remove_task_item, list); @@ -367,15 +367,15 @@ GtkWidget *task_list_new (WpApplet *windowPickerApplet) { return (GtkWidget *) taskList; } -gint +GdkMonitor * task_list_get_monitor (TaskList *list) { - GdkScreen *gdk_screen; + GdkDisplay *gdk_display; GdkWindow *gdk_window; + gdk_display = gdk_display_get_default (); gdk_window = gtk_widget_get_window (GTK_WIDGET (list)); - gdk_screen = gtk_widget_get_screen (GTK_WIDGET (list)); - return gdk_screen_get_monitor_at_window (gdk_screen, - gdk_window); + return gdk_display_get_monitor_at_window (gdk_display, + gdk_window); } diff --git a/windowpicker/src/task-list.h b/windowpicker/src/task-list.h index 582c89bbf..ea37cc1da 100644 --- a/windowpicker/src/task-list.h +++ b/windowpicker/src/task-list.h @@ -55,9 +55,9 @@ struct _TaskListClass { GtkBoxClass parent_class; }; -GType task_list_get_type (void) G_GNUC_CONST; +GType task_list_get_type (void) G_GNUC_CONST; -GtkWidget *task_list_new (WpApplet *applet); -gint task_list_get_monitor (TaskList *list); +GtkWidget *task_list_new (WpApplet *applet); +GdkMonitor *task_list_get_monitor (TaskList *list); #endif /* _TASK_LIST_H_ */ -- GitLab