[gnome-applets/wip-geiger-task-item] window-picker: handle item lifecycle in TaskList



commit 5e522ee97a51bc0c67de9bc9b1a41e5d1454cd40
Author: Sebastian Geiger <sbastig gmx net>
Date:   Wed Apr 1 00:34:41 2020 +0200

    window-picker: handle item lifecycle in TaskList

 gnome-applets/window-picker/task-item.c | 58 ++------------------
 gnome-applets/window-picker/task-list.c | 96 ++++++++++++++++++++++-----------
 2 files changed, 70 insertions(+), 84 deletions(-)
---
diff --git a/gnome-applets/window-picker/task-item.c b/gnome-applets/window-picker/task-item.c
index aeacde419..143994dda 100644
--- a/gnome-applets/window-picker/task-item.c
+++ b/gnome-applets/window-picker/task-item.c
@@ -47,7 +47,6 @@ G_DEFINE_TYPE (TaskItem, task_item, GTK_TYPE_EVENT_BOX)
 #define DEFAULT_TASK_ITEM_WIDTH 28 + 2
 
 enum {
-    TASK_ITEM_CLOSED_SIGNAL,
     TASK_ITEM_MONITOR_CHANGED,
     LAST_SIGNAL
 };
@@ -77,8 +76,6 @@ static const GtkTargetEntry drag_types[] = {
 
 static const gint n_drag_types = G_N_ELEMENTS(drag_types);
 
-static void task_item_close (TaskItem *item);
-
 static void
 update_expand (TaskItem       *self,
                GtkOrientation  orientation)
@@ -542,26 +539,6 @@ static void on_window_icon_changed (WnckWindow *window, TaskItem *item) {
     gtk_widget_queue_draw (GTK_WIDGET (item));
 }
 
-static void
-on_window_type_changed (WnckWindow *window,
-                        TaskItem *item)
-{
-    WnckWindowType type;
-
-    if (item->window != window)
-        return;
-
-    type = wnck_window_get_window_type (window);
-
-    if (type == WNCK_WINDOW_DESKTOP ||
-        type == WNCK_WINDOW_DOCK ||
-        type == WNCK_WINDOW_SPLASHSCREEN ||
-        type == WNCK_WINDOW_MENU)
-      {
-          task_item_close (item);
-      }
-}
-
 static GdkMonitor *
 get_window_monitor (WnckWindow *window)
 {
@@ -650,25 +627,6 @@ static void on_screen_active_viewport_changed (
     task_item_set_visibility (item);
 }
 
-static void on_screen_window_closed (
-    WnckScreen   *screen,
-    WnckWindow   *window,
-    TaskItem     *item)
-{
-    g_return_if_fail (TASK_IS_ITEM(item));
-    g_return_if_fail (WNCK_IS_WINDOW (item->window));
-    if (item->window == window) {
-        task_item_close (item);
-    }
-}
-
-static void
-task_item_close (TaskItem   *item)
-{
-    g_signal_emit (G_OBJECT (item),
-                   task_item_signals[TASK_ITEM_CLOSED_SIGNAL], 0);
-}
-
 static gboolean activate_window (GtkWidget *widget) {
     TaskItem *item;
     GtkWidget *parent;
@@ -991,6 +949,7 @@ static void task_item_finalize (GObject *object) {
     }
 
     g_clear_object (&item->pixbuf);
+    g_clear_object (&item->window);
 
     G_OBJECT_CLASS (task_item_parent_class)->finalize (object);
 }
@@ -1007,14 +966,6 @@ static void task_item_class_init (TaskItemClass *klass) {
     widget_class->get_preferred_height = task_item_get_preferred_height;
     widget_class->get_preferred_height_for_width = task_item_get_preferred_height_for_width;
 
-    task_item_signals [TASK_ITEM_CLOSED_SIGNAL] =
-    g_signal_new ("task-item-closed",
-        G_TYPE_FROM_CLASS (klass),
-        G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
-        0,
-        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, 0);
@@ -1041,7 +992,10 @@ GtkWidget *task_item_new (WpApplet* windowPickerApplet, WnckWindow *window) {
     gtk_widget_add_events (item, GDK_ALL_EVENTS_MASK);
     gtk_container_set_border_width (GTK_CONTAINER (item), 0);
     taskItem = TASK_ITEM (item);
+
     taskItem->window = window;
+    g_object_ref (taskItem->window);
+
     screen = wnck_window_get_screen (window);
     taskItem->screen = screen;
     taskItem->windowPickerApplet = windowPickerApplet;
@@ -1109,16 +1063,12 @@ GtkWidget *task_item_new (WpApplet* windowPickerApplet, WnckWindow *window) {
         G_CALLBACK (on_screen_active_window_changed), item, 0);
     g_signal_connect_object (screen, "active-workspace-changed",
         G_CALLBACK (on_screen_active_workspace_changed), item, 0);
-    g_signal_connect_object (screen, "window-closed",
-        G_CALLBACK (on_screen_window_closed), item, 0);
     g_signal_connect_object (window, "workspace-changed",
         G_CALLBACK (on_window_workspace_changed), item, 0);
     g_signal_connect_object (window, "state-changed",
         G_CALLBACK (on_window_state_changed), item, 0);
     g_signal_connect_object (window, "icon-changed",
         G_CALLBACK (on_window_icon_changed), item, 0);
-    g_signal_connect_object (window, "type-changed",
-        G_CALLBACK (on_window_type_changed), item, 0);
     g_signal_connect_object (window, "geometry-changed",
         G_CALLBACK (on_window_geometry_changed), item, 0);
 
diff --git a/gnome-applets/window-picker/task-list.c b/gnome-applets/window-picker/task-list.c
index 126f73f34..393b4a518 100644
--- a/gnome-applets/window-picker/task-list.c
+++ b/gnome-applets/window-picker/task-list.c
@@ -28,6 +28,7 @@
 struct _TaskList {
     GtkBox parent;
     WnckScreen *screen;
+    GHashTable *items;
     WpApplet *windowPickerApplet;
     guint init_windows_event_source;
 };
@@ -70,15 +71,6 @@ get_task_list_for_monitor (GdkMonitor *monitor)
     return task_lists->data;
 }
 
-
-static void on_task_item_closed (
-    TaskItem *item,
-    TaskList *list)
-{
-    gtk_container_remove (GTK_CONTAINER (list),
-                          GTK_WIDGET (item));
-}
-
 static GdkMonitor *
 window_get_monitor (WnckWindow *window)
 {
@@ -129,7 +121,8 @@ on_task_item_monitor_changed_cb (TaskItem *item,
       }
 }
 
-static void create_task_item (TaskList   *taskList,
+static GtkWidget *
+create_task_item (TaskList   *taskList,
                               WnckWindow *window)
 {
     GtkWidget *item;
@@ -145,7 +138,7 @@ static void create_task_item (TaskList   *taskList,
         window_monitor = window_get_monitor (window);
 
         if (list_monitor != window_monitor)
-            return;
+            return NULL;
       }
 
     item = task_item_new (taskList->windowPickerApplet,
@@ -155,13 +148,12 @@ static void create_task_item (TaskList   *taskList,
       {
         gtk_container_add (GTK_CONTAINER (taskList), item);
 
-        g_signal_connect_object (TASK_ITEM (item), "task-item-closed",
-                                 G_CALLBACK (on_task_item_closed), taskList, 0);
-
         g_signal_connect_object (TASK_ITEM (item), "monitor-changed",
                                  G_CALLBACK (on_task_item_monitor_changed_cb),
                                  taskList, 0);
       }
+
+    return item;
 }
 
 static void type_changed (WnckWindow *window,
@@ -171,7 +163,12 @@ static void type_changed (WnckWindow *window,
 
     if (!window_is_special (window))
       {
-        create_task_item (taskList, window);
+        GtkWidget * item;
+
+        item = create_task_item (taskList, window);
+
+        if (item)
+          g_hash_table_insert (taskList->items, window, item);
       }
 }
 
@@ -188,15 +185,6 @@ on_task_list_placement_changed (GpApplet        *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 void
 clear_windows (TaskList *list)
 {
@@ -209,21 +197,24 @@ clear_windows (TaskList *list)
                                                     window);
 
   if (task_list_get_monitor (list) == list_monitor)
-    gtk_container_foreach (GTK_CONTAINER (list), remove_task_item, list);
+    g_hash_table_remove_all (list->items);
 }
 
-static void
+static GtkWidget *
 add_window (TaskList *list, WnckWindow *window)
 {
+  GtkWidget *item;
+
   g_signal_connect_object (window, "type-changed", G_CALLBACK (type_changed),
                            list, 0);
 
   if (window_is_special (window))
-  {
-    return;
-  }
+    return NULL;
+
+  item = create_task_item (list, window);
 
-  create_task_item (list, window);
+  if (item)
+    g_hash_table_insert (list->items, window, item);
 }
 
 static void
@@ -241,12 +232,50 @@ add_windows (TaskList *list)
   }
 }
 
+static void
+on_window_type_changed (WnckWindow *window,
+                        TaskList *list)
+{
+    TaskItem *item;
+    WnckWindowType type;
+
+    item = g_hash_table_lookup (list->items, window);
+
+    if (!item)
+        return;
+
+    type = wnck_window_get_window_type (window);
+
+    if (type == WNCK_WINDOW_DESKTOP ||
+        type == WNCK_WINDOW_DOCK ||
+        type == WNCK_WINDOW_SPLASHSCREEN ||
+        type == WNCK_WINDOW_MENU)
+    {
+        g_hash_table_remove (list->items, item);
+    }
+}
+
 static void
 on_window_opened (WnckScreen *screen,
                   WnckWindow *window,
                   TaskList   *taskList)
 {
   add_window (taskList, window);
+
+  g_signal_connect_object (window, "type-changed",
+                           G_CALLBACK (on_window_type_changed), taskList, 0);
+}
+
+static void
+on_window_closed (WnckScreen *screen,
+                  WnckWindow *window,
+                  TaskList *taskList)
+{
+    TaskItem * item;
+
+    item = g_hash_table_lookup (taskList->items, window);
+
+    g_hash_table_remove (taskList->items, item);
 }
 
 static gboolean
@@ -329,6 +358,10 @@ task_list_class_init(TaskListClass *class) {
 
 static void task_list_init (TaskList *list) {
     list->screen = wnck_screen_get_default ();
+
+    list->items = g_hash_table_new_full (NULL, NULL,
+                                         NULL, (GDestroyNotify) gtk_widget_destroy);
+
     gtk_container_set_border_width (GTK_CONTAINER (list), 0);
 }
 
@@ -353,6 +386,9 @@ GtkWidget *task_list_new (WpApplet *windowPickerApplet) {
     g_signal_connect_object (taskList->screen, "window-opened",
                              G_CALLBACK (on_window_opened), taskList, 0);
 
+    g_signal_connect_object (taskList->screen, "window-closed",
+                             G_CALLBACK (on_window_closed), taskList, 0);
+
     gdk_window_add_filter (gtk_widget_get_window (GTK_WIDGET (taskList)),
                            window_filter_function,
                            taskList);


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