[gnome-applets/wip/segeiger/type-changed: 5/5] windowpicker: handle to monitor-geometry changed signal
- From: Sebastian Geiger <segeiger src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-applets/wip/segeiger/type-changed: 5/5] windowpicker: handle to monitor-geometry changed signal
- Date: Sun, 14 Feb 2016 00:00:52 +0000 (UTC)
commit 60e232ea7d37a00f2cc3e1a00834e5d78b4822f2
Author: Sebastian Geiger <sbastig gmx net>
Date: Mon Feb 8 01:34:24 2016 +0100
windowpicker: handle to monitor-geometry changed signal
Works but still needs some cleanup.
windowpicker/src/task-item.c | 66 +++++++++++++++-
windowpicker/src/task-item.h | 3 +
windowpicker/src/task-list.c | 174 +++++++++++++++++++++++++++++++++++++-----
windowpicker/src/task-list.h | 14 +++-
4 files changed, 233 insertions(+), 24 deletions(-)
---
diff --git a/windowpicker/src/task-item.c b/windowpicker/src/task-item.c
index 389354e..70c8115 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
};
@@ -78,7 +80,7 @@ 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 task_item_close (TaskItem *item);
static void update_hints (TaskItem *item) {
GtkWidget *parent, *widget;
@@ -482,10 +484,52 @@ on_window_type_changed (WnckWindow *window,
type == WNCK_WINDOW_SPLASHSCREEN ||
type == WNCK_WINDOW_MENU)
{
- task_item_close (item, window);
+ task_item_close (item);
}
}
+gint get_window_monitor (WnckWindow *window)
+{
+ gint x, y, w, 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;
+ gboolean handled;
+
+ //g_signal_handlers_block_by_func (window, on_window_geometry_changed, item);
+
+ window_monitor = get_window_monitor (window);
+
+ old_monitor = item->priv->monitor;
+ if (old_monitor != window_monitor)
+ {
+ item->priv->monitor = window_monitor;
+ g_message ("old_monitor=%d, window_monitor=%d, emitting signal", old_monitor,
+ window_monitor);
+
+ g_signal_emit (item, task_item_signals[TASK_ITEM_MONITOR_CHANGED], 0,
+ old_monitor, &handled);
+ }
+
+ //g_signal_handlers_unblock_by_func (window, on_window_geometry_changed,
+ // item);
+}
+
static void on_screen_active_window_changed (
WnckScreen *screen,
WnckWindow *old_window,
@@ -810,6 +854,14 @@ 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,
+ G_STRUCT_OFFSET (TaskItemClass, monitor_changed),
+ g_signal_accumulator_true_handled, NULL, NULL,
+ G_TYPE_BOOLEAN, 1, G_TYPE_INT);
}
static void task_item_init (TaskItem *item) {
@@ -838,6 +890,9 @@ 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);
+
+ g_message ("item=%p on monitor=%d", item, priv->monitor);
/** Drag and Drop code
* This item can be both the target and the source of a drag and drop
@@ -899,6 +954,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 +974,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..0ea6b10 100644
--- a/windowpicker/src/task-item.h
+++ b/windowpicker/src/task-item.h
@@ -46,9 +46,12 @@ struct _TaskItem {
struct _TaskItemClass {
GtkEventBoxClass parent_class;
void (* itemclosed) (TaskItem *item);
+ void (* monitor_changed) (TaskItem *item);
};
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 c198415..19e82b7 100644
--- a/windowpicker/src/task-list.c
+++ b/windowpicker/src/task-list.c
@@ -29,9 +29,67 @@ struct _TaskListPrivate {
WpApplet *windowPickerApplet;
};
-static GSList *task_lists;
+struct _TaskListClassPrivate {
+ GSList *task_lists;
+};
+
+G_DEFINE_TYPE_WITH_CODE (TaskList, task_list, GTK_TYPE_BOX,
+ G_ADD_PRIVATE (TaskList);
+ g_type_add_class_private (g_define_type_id,
+ sizeof (TaskListClassPrivate)))
+
+static guint
+get_num_task_lists (TaskList *task_list)
+{
+ TaskListClassPrivate *class_private = TASK_LIST_GET_CLASS_PRIVATE (task_list);
+
+ return g_slist_length (class_private->task_lists);
+}
+
+static void
+add_task_list (TaskList *task_list)
+{
+ TaskListClassPrivate *class_private = TASK_LIST_GET_CLASS_PRIVATE (task_list);
+
+ class_private->task_lists = g_slist_append (class_private->task_lists,
+ task_list);
+}
+
+static void
+remove_task_list (TaskList *task_list)
+{
+ TaskListClassPrivate *class_private = TASK_LIST_GET_CLASS_PRIVATE (task_list);
+
+ class_private->task_lists = g_slist_remove (class_private->task_lists,
+ task_list);
+}
+
+static TaskList *
+get_task_list_for_monitor (TaskList *task_list,
+ guint monitor)
+{
+ GSList *list;
+ gint list_monitor;
+
+ TaskListClassPrivate *class_private =
+ TASK_LIST_GET_CLASS_PRIVATE (task_list);
+
+ list = class_private->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 class_private->task_lists->data;
+}
-G_DEFINE_TYPE_WITH_PRIVATE (TaskList, task_list, GTK_TYPE_BOX);
static void on_task_item_closed (
TaskItem *item,
@@ -44,25 +102,80 @@ 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;
+
+ g_message ("on_task_item_monitor_changed");
+
+ monitor = task_item_get_monitor (item);
+ list_monitor = task_list_get_monitor (current_list);
+
+ g_message ("monitor=%d, list_monitor=%d", monitor, list_monitor);
+
+ if (monitor != list_monitor)
+ {
+
+ list = TASK_LIST (get_task_list_for_monitor (current_list,
+ monitor));
+
+ g_object_ref (item);
+ gtk_container_remove (GTK_CONTAINER (current_list), GTK_WIDGET (item));
+
+ 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));
+ gtk_widget_queue_draw (GTK_WIDGET (list));
+
+ }
+
+ // some things to consider:
+ // What if two task lists are on the same monitor?
+}
+
static void create_task_item (TaskList *taskList,
WnckWindow *window)
{
- GdkScreen *gdk_screen;
- GdkWindow *gdk_window;
gint list_monitor, window_monitor;
- gint x, y, w, h;
+ guint num;
- if (g_slist_length (task_lists) > 1) {
- gdk_window = gtk_widget_get_window (GTK_WIDGET (taskList));
- gdk_screen = gtk_widget_get_screen (GTK_WIDGET (taskList));
- list_monitor = gdk_screen_get_monitor_at_window (gdk_screen,
- gdk_window);
+ num = get_num_task_lists (taskList);
- wnck_window_get_geometry (window, &x, &y, &w, &h);
+ g_message ("number of task_lists=%d", num);
- window_monitor = gdk_screen_get_monitor_at_point (gdk_screen,
- x + w / 2,
- y + h / 2);
+ if (num > 1) {
+ list_monitor = task_list_get_monitor (taskList);
+ window_monitor = window_get_monitor (window);
if (list_monitor != window_monitor)
return;
@@ -74,8 +187,16 @@ static void create_task_item (TaskList *taskList,
if (item) {
//we add items dynamically to the end of the list
gtk_container_add (GTK_CONTAINER(taskList), item);
- g_signal_connect (TASK_ITEM (item), "task-item-closed",
- G_CALLBACK (on_task_item_closed), taskList);
+
+ g_message ("adding item to list: %p", item);
+ // the ALT+F2 dialog seems to appear twice for a brief second when the
+ // dialog is being closed. I need to verify if the gtk_widget_destroy
+ // change is causing this.
+
+ g_signal_connect (TASK_ITEM (item), "monitor-changed",
+ G_CALLBACK (on_task_item_monitor_changed_cb),
+ taskList);
+
}
}
@@ -146,7 +267,11 @@ task_list_dispose (GObject *object)
static void
task_list_finalize (GObject *object)
{
- task_lists = g_slist_remove (task_lists, object);
+ TaskList *taskList;
+
+ taskList = TASK_LIST (object);
+
+ remove_task_list (taskList);
G_OBJECT_CLASS (task_list_parent_class)->finalize (object);
}
@@ -186,7 +311,7 @@ GtkWidget *task_list_new (WpApplet *windowPickerApplet) {
NULL
);
- task_lists = g_slist_append (task_lists, taskList);
+ add_task_list (taskList);
taskList->priv->windowPickerApplet = windowPickerApplet;
@@ -202,3 +327,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);
+}
\ No newline at end of file
diff --git a/windowpicker/src/task-list.h b/windowpicker/src/task-list.h
index 3fb4631..ae52620 100644
--- a/windowpicker/src/task-list.h
+++ b/windowpicker/src/task-list.h
@@ -42,9 +42,14 @@
#define TASK_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
TASK_TYPE_LIST, TaskListClass))
-typedef struct _TaskList TaskList;
-typedef struct _TaskListClass TaskListClass;
-typedef struct _TaskListPrivate TaskListPrivate;
+#define TASK_LIST_GET_CLASS_PRIVATE(obj) (G_TYPE_CLASS_GET_PRIVATE ( \
+ TASK_LIST_GET_CLASS ((obj)), \
+ TASK_TYPE_LIST, TaskListClassPrivate))
+
+typedef struct _TaskList TaskList;
+typedef struct _TaskListClass TaskListClass;
+typedef struct _TaskListPrivate TaskListPrivate;
+typedef struct _TaskListClassPrivate TaskListClassPrivate;
struct _TaskList {
GtkBox parent;
@@ -52,11 +57,12 @@ struct _TaskList {
};
struct _TaskListClass {
- GtkBoxClass parent_class;
+ 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);
+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]