[gnome-applets/wip/segeiger/type-changed] windowpicker: let TaskList only show windows from same monitor



commit 5d4b456db243fadecef1f21500254cdc4b7efda8
Author: Sebastian Geiger <sbastig gmx net>
Date:   Thu Jan 21 14:51:00 2016 +0100

    windowpicker: let TaskList only show windows from same monitor
    
     * This patch makes a given tasklist ignore windows that
       are not on the same monitor as the tasklist, if there is more than one
       task list added to gnome-panel. If a window moves from one monitor
       to another, then its corresponding TaskItem is removed from its
       TaskList and added to the TaskList of the other monitor.

 windowpicker/src/task-item.c |   54 +++++++++++++++++++-
 windowpicker/src/task-item.h |    2 +
 windowpicker/src/task-list.c |  118 +++++++++++++++++++++++++++++++++++++++++-
 windowpicker/src/task-list.h |    7 ++-
 4 files changed, 175 insertions(+), 6 deletions(-)
---
diff --git a/windowpicker/src/task-item.c b/windowpicker/src/task-item.c
index d781486..389d8c5 100644
--- a/windowpicker/src/task-item.c
+++ b/windowpicker/src/task-item.c
@@ -43,11 +43,13 @@ struct _TaskItemPrivate {
     GTimeVal     urgent_time;
     guint        blink_timer;
     gboolean     mouse_over;
+    gint         monitor;
     WpApplet    *windowPickerApplet;
 };
 
 enum {
     TASK_ITEM_CLOSED_SIGNAL,
+    TASK_ITEM_MONITOR_CHANGED,
     LAST_SIGNAL
 };
 
@@ -482,7 +484,45 @@ on_window_type_changed (WnckWindow *window,
         type == WNCK_WINDOW_SPLASHSCREEN ||
         type == WNCK_WINDOW_MENU)
       {
-          task_item_close (item, window);
+          task_item_close (item);
+      }
+}
+
+static gint
+get_window_monitor (WnckWindow *window)
+{
+    gint x;
+    gint y;
+    gint w;
+    gint h;
+    gint window_monitor;
+    GdkScreen *gdk_screen;
+
+    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);
+    return window_monitor;
+}
+
+static void
+on_window_geometry_changed (WnckWindow *window,
+                            TaskItem   *item)
+{
+    gint old_monitor;
+    gint window_monitor;
+
+    window_monitor = get_window_monitor (window);
+
+    old_monitor = item->priv->monitor;
+    if (old_monitor != window_monitor)
+      {
+        item->priv->monitor = window_monitor;
+
+        g_signal_emit (item, task_item_signals[TASK_ITEM_MONITOR_CHANGED], 0,
+                       old_monitor);
       }
 }
 
@@ -810,6 +850,10 @@ static void task_item_class_init (TaskItemClass *klass) {
         G_STRUCT_OFFSET (TaskItemClass, itemclosed),
         NULL, NULL,
         g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+    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);
 }
 
 static void task_item_init (TaskItem *item) {
@@ -838,6 +882,7 @@ GtkWidget *task_item_new (WpApplet* windowPickerApplet, WnckWindow *window) {
     screen = wnck_window_get_screen (window);
     priv->screen = screen;
     priv->windowPickerApplet = windowPickerApplet;
+    priv->monitor = get_window_monitor (window);
 
     /** Drag and Drop code
      * This item can be both the target and the source of a drag and drop
@@ -899,6 +944,8 @@ GtkWidget *task_item_new (WpApplet* windowPickerApplet, WnckWindow *window) {
         G_CALLBACK (on_window_icon_changed), item);
     g_signal_connect (window, "type-changed",
         G_CALLBACK (on_window_type_changed), item);
+    g_signal_connect (window, "geometry-changed",
+        G_CALLBACK (on_window_geometry_changed), item);
     g_signal_connect(item, "draw",
         G_CALLBACK(task_item_draw), windowPickerApplet);
     g_signal_connect (item, "button-release-event",
@@ -917,3 +964,8 @@ GtkWidget *task_item_new (WpApplet* windowPickerApplet, WnckWindow *window) {
     task_item_setup_atk (taskItem);
     return item;
 }
+
+gint 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 dcb9a0e..666513d 100644
--- a/windowpicker/src/task-item.h
+++ b/windowpicker/src/task-item.h
@@ -51,4 +51,6 @@ struct _TaskItemClass {
 GType task_item_get_type (void) G_GNUC_CONST;
 GtkWidget * task_item_new (WpApplet *windowPickerApplet, WnckWindow *window);
 
+gint        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 fa965f2..312f59c 100644
--- a/windowpicker/src/task-list.c
+++ b/windowpicker/src/task-list.c
@@ -31,6 +31,32 @@ struct _TaskListPrivate {
 
 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)
+{
+    GSList *list;
+    gint list_monitor;
+
+    list = task_lists;
+
+    while (list != NULL)
+      {
+        task_list = list->data;
+        list_monitor = task_list_get_monitor (task_list);
+
+        if (list_monitor == monitor)
+            return task_list;
+
+        list = list->next;
+      }
+
+    return task_lists->data;
+}
+
+
 static void on_task_item_closed (
     TaskItem *item,
     TaskList *list)
@@ -42,10 +68,75 @@ static void on_task_item_closed (
     gtk_widget_destroy (GTK_WIDGET (item));
 }
 
+static gint
+window_get_monitor (WnckWindow *window)
+{
+    GdkScreen *gdk_screen;
+    gint x, y, w, h;
+
+    gdk_screen = gdk_screen_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);
+}
+
+static void
+on_task_item_monitor_changed_cb (TaskItem *item,
+                                 gint      old_monitor,
+                                 TaskList *current_list)
+{
+    gint monitor;
+    gint list_monitor;
+    TaskList *list;
+
+    monitor = task_item_get_monitor (item);
+    list_monitor = task_list_get_monitor (current_list);
+
+    if (monitor != list_monitor)
+      {
+        list = get_task_list_for_monitor (current_list, monitor);
+
+        g_object_ref (item);
+        gtk_container_remove (GTK_CONTAINER (current_list), GTK_WIDGET (item));
+
+        gtk_widget_queue_resize (GTK_WIDGET (current_list));
+
+        g_signal_handlers_disconnect_by_func (item,
+                                              on_task_item_monitor_changed_cb,
+                                              current_list);
+
+        gtk_container_add (GTK_CONTAINER (list), GTK_WIDGET (item));
+
+        g_signal_connect (TASK_ITEM (item), "monitor-changed",
+                          G_CALLBACK (on_task_item_monitor_changed_cb), list);
+
+        g_object_unref (item);
+
+        gtk_widget_queue_resize (GTK_WIDGET (list));
+      }
+}
+
 static void create_task_item (TaskList   *taskList,
                               WnckWindow *window)
 {
     GtkWidget *item;
+    gint list_monitor;
+    gint window_monitor;
+    guint num;
+
+    num = g_slist_length (task_lists);
+
+    if (num > 1)
+      {
+        list_monitor = task_list_get_monitor (taskList);
+        window_monitor = window_get_monitor (window);
+
+        if (list_monitor != window_monitor)
+            return;
+      }
 
     item = task_item_new (taskList->priv->windowPickerApplet,
                           window);
@@ -53,8 +144,13 @@ static void create_task_item (TaskList   *taskList,
     if (item)
       {
         gtk_container_add (GTK_CONTAINER (taskList), item);
+
         g_signal_connect (TASK_ITEM (item), "task-item-closed",
                           G_CALLBACK (on_task_item_closed), taskList);
+
+        g_signal_connect (TASK_ITEM (item), "monitor-changed",
+                          G_CALLBACK (on_task_item_monitor_changed_cb),
+                          taskList);
       }
 }
 
@@ -127,8 +223,11 @@ task_list_dispose (GObject *object)
 static void
 task_list_finalize (GObject *object)
 {
-    TaskList *task_list = TASK_LIST (object);
-    TaskListPrivate *priv = task_list->priv;
+    TaskList *taskList;
+
+    taskList = TASK_LIST (object);
+
+    task_lists = g_slist_remove (task_lists, taskList);
 
     G_OBJECT_CLASS (task_list_parent_class)->finalize (object);
 }
@@ -168,6 +267,8 @@ GtkWidget *task_list_new (WpApplet *windowPickerApplet) {
                                        NULL
     );
 
+    task_lists = g_slist_append (task_lists, taskList);
+
     taskList->priv->windowPickerApplet = windowPickerApplet;
 
     g_signal_connect(PANEL_APPLET(windowPickerApplet), "change-orient",
@@ -182,3 +283,16 @@ GtkWidget *task_list_new (WpApplet *windowPickerApplet) {
     }
     return (GtkWidget *) taskList;
 }
+
+gint
+task_list_get_monitor (TaskList *list)
+{
+    GdkScreen *gdk_screen;
+    GdkWindow *gdk_window;
+
+    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);
+}
diff --git a/windowpicker/src/task-list.h b/windowpicker/src/task-list.h
index 3fb4631..582c89b 100644
--- a/windowpicker/src/task-list.h
+++ b/windowpicker/src/task-list.h
@@ -55,8 +55,9 @@ struct _TaskListClass {
     GtkBoxClass parent_class;
 };
 
-GType task_list_get_type (void) G_GNUC_CONST;
-GtkWidget * task_list_new (WpApplet* windowPickerApplet);
-gboolean    task_list_get_desktop_visible (TaskList *list);
+GType      task_list_get_type            (void) G_GNUC_CONST;
+
+GtkWidget *task_list_new                 (WpApplet *applet);
+gint       task_list_get_monitor         (TaskList *list);
 
 #endif /* _TASK_LIST_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]