[gnome-applets/wip/windowpicker: 1/2] windowpicker: fix item assignment on workarea change
- From: Sebastian Geiger <segeiger src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-applets/wip/windowpicker: 1/2] windowpicker: fix item assignment on workarea change
- Date: Fri, 14 Dec 2018 15:59:00 +0000 (UTC)
commit 6651d5cfd2aeb4741935f9f5211dc97e970b9c4d
Author: Sebastian Geiger <sbastig gmx net>
Date: Sun Dec 9 17:16:56 2018 +0100
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 | 101 ++++++++++++++++++++++++++++++++++++++++---
3 files changed, 101 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..ebeeb78b4 100644
--- a/windowpicker/src/task-list.c
+++ b/windowpicker/src/task-list.c
@@ -23,10 +23,12 @@
#include <libwnck/libwnck.h>
#include <panel-applet.h>
+#include <X11/Xlib.h>
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,90 @@ 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));
+
+ g_signal_handlers_block_by_func (list->priv->screen,
+ on_window_opened,
+ 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;
+ }
+
+ g_signal_handlers_unblock_by_func (list->priv->screen,
+ on_window_opened,
+ NULL);
+
+ 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 +312,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 +363,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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]