[notification-daemon] Also respond to monitor size changes
- From: William Jon McCann <mccann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [notification-daemon] Also respond to monitor size changes
- Date: Sat, 26 Jun 2010 23:18:41 +0000 (UTC)
commit 7889698ec9041c0979869e6d9230acc29dee159d
Author: William Jon McCann <jmccann redhat com>
Date: Thu Jun 24 14:35:17 2010 -0400
Also respond to monitor size changes
By watching for changes to _NET_WORKAREA. Responding to changes
in screen or monitor size isn't enough since we compute the position
relative to the work area.
https://bugzilla.gnome.org/show_bug.cgi?id=622552
src/daemon/daemon.c | 63 +++++++++++++++++++++++++++++++++++---------------
src/daemon/stack.c | 54 +++++++++++++++++++++++++++++++++++--------
src/daemon/stack.h | 1 +
3 files changed, 89 insertions(+), 29 deletions(-)
---
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index a96c274..af93fce 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -97,6 +97,7 @@ typedef struct
{
NotifyStack **stacks;
int n_stacks;
+ Atom workarea_atom;
} NotifyScreen;
struct _NotifyDaemonPrivate
@@ -233,13 +234,7 @@ on_screen_monitors_changed (GdkScreen *screen,
n_monitors = gdk_screen_get_n_monitors (screen);
- g_debug ("Monitors changed for screen %d: num=%d",
- screen_num,
- n_monitors);
-
- if (n_monitors == nscreen->n_stacks) {
- return;
- } else if (n_monitors > nscreen->n_stacks) {
+ if (n_monitors > nscreen->n_stacks) {
/* grow */
nscreen->stacks = g_renew (NotifyStack *,
nscreen->stacks,
@@ -251,7 +246,7 @@ on_screen_monitors_changed (GdkScreen *screen,
}
nscreen->n_stacks = n_monitors;
- } else {
+ } else if (n_monitors < nscreen->n_stacks) {
NotifyStack *last_stack;
last_stack = nscreen->stacks[n_monitors - 1];
@@ -265,11 +260,6 @@ on_screen_monitors_changed (GdkScreen *screen,
stack = nscreen->stacks[i];
windows = g_list_copy (notify_stack_get_windows (stack));
for (l = windows; l != NULL; l = l->next) {
- g_debug ("Transferring window %p from %d to %d",
- l->data,
- i,
- n_monitors - 1);
-
/* skip removing the window from the
old stack since it will try to
unrealize the window. And the
@@ -306,15 +296,32 @@ create_stacks_for_screen (NotifyDaemon *daemon,
nscreen->stacks,
nscreen->n_stacks);
- g_debug ("Creating %d stacks for screen %d",
- nscreen->n_stacks,
- screen_num);
-
for (i = 0; i < nscreen->n_stacks; i++) {
create_stack_for_monitor (daemon, screen, i);
}
}
+static GdkFilterReturn
+screen_xevent_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ NotifyScreen *nscreen)
+{
+ XEvent *xev;
+
+ xev = (XEvent *) xevent;
+
+ if (xev->type == PropertyNotify &&
+ xev->xproperty.atom == nscreen->workarea_atom) {
+ int i;
+
+ for (i = 0; i < nscreen->n_stacks; i++) {
+ notify_stack_queue_update_position (nscreen->stacks[i]);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
static void
create_screens (NotifyDaemon *daemon)
{
@@ -329,11 +336,22 @@ create_screens (NotifyDaemon *daemon)
daemon->priv->screens = g_new0 (NotifyScreen *, daemon->priv->n_screens);
for (i = 0; i < daemon->priv->n_screens; i++) {
- g_signal_connect (gdk_display_get_screen (display, i),
+ GdkScreen *screen;
+ GdkWindow *gdkwindow;
+
+ screen = gdk_display_get_screen (display, i);
+ g_signal_connect (screen,
"monitors-changed",
G_CALLBACK (on_screen_monitors_changed),
daemon);
+
daemon->priv->screens[i] = g_new0 (NotifyScreen, 1);
+
+ daemon->priv->screens[i]->workarea_atom = XInternAtom (GDK_DISPLAY (), "_NET_WORKAREA", True);
+ gdkwindow = gdk_screen_get_root_window (screen);
+ gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, daemon->priv->screens[i]);
+ gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK);
+
create_stacks_for_screen (daemon, gdk_display_get_screen (display, i));
}
}
@@ -434,9 +452,16 @@ destroy_screens (NotifyDaemon *daemon)
display = gdk_display_get_default ();
for (i = 0; i < daemon->priv->n_screens; i++) {
- g_signal_handlers_disconnect_by_func (gdk_display_get_screen (display, i),
+ GdkScreen *screen;
+ GdkWindow *gdkwindow;
+
+ screen = gdk_display_get_screen (display, i);
+ g_signal_handlers_disconnect_by_func (screen,
G_CALLBACK (on_screen_monitors_changed),
daemon);
+
+ gdkwindow = gdk_screen_get_root_window (screen);
+ gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, daemon->priv->screens[i]);
for (j = 0; i < daemon->priv->screens[i]->n_stacks; j++) {
notify_stack_destroy (daemon->priv->screens[i]->stacks[j]);
daemon->priv->screens[i]->stacks[j] = NULL;
diff --git a/src/daemon/stack.c b/src/daemon/stack.c
index 20447a4..936edbe 100644
--- a/src/daemon/stack.c
+++ b/src/daemon/stack.c
@@ -39,6 +39,7 @@ struct _NotifyStack
guint monitor;
NotifyStackLocation location;
GList *windows;
+ guint update_id;
};
GList *
@@ -48,7 +49,7 @@ notify_stack_get_windows (NotifyStack *stack)
}
static gboolean
-get_work_area (GtkWidget *nw,
+get_work_area (NotifyStack *stack,
GdkRectangle *rect)
{
Atom workarea;
@@ -61,19 +62,17 @@ get_work_area (GtkWidget *nw,
guchar *ret_workarea;
long *workareas;
int result;
- GdkScreen *screen;
int disp_screen;
workarea = XInternAtom (GDK_DISPLAY (), "_NET_WORKAREA", True);
- gtk_widget_realize (nw);
- screen = gdk_drawable_get_screen (GDK_DRAWABLE (nw->window));
- disp_screen = GDK_SCREEN_XNUMBER (screen);
+
+ disp_screen = GDK_SCREEN_XNUMBER (stack->screen);
/* Defaults in case of error */
rect->x = 0;
rect->y = 0;
- rect->width = gdk_screen_get_width (screen);
- rect->height = gdk_screen_get_height (screen);
+ rect->width = gdk_screen_get_width (stack->screen);
+ rect->height = gdk_screen_get_height (stack->screen);
if (workarea == None)
return FALSE;
@@ -214,6 +213,10 @@ notify_stack_destroy (NotifyStack *stack)
{
g_assert (stack != NULL);
+ if (stack->update_id != 0) {
+ g_source_remove (stack->update_id);
+ }
+
g_list_free (stack->windows);
g_free (stack);
}
@@ -258,7 +261,7 @@ notify_stack_shift_notifications (NotifyStack *stack,
int i;
int n_wins;
- get_work_area (GTK_WIDGET (nw), &workarea);
+ get_work_area (stack, &workarea);
gdk_screen_get_monitor_geometry (stack->screen,
stack->monitor,
&monitor);
@@ -287,7 +290,7 @@ notify_stack_shift_notifications (NotifyStack *stack,
GtkWindow *nw2 = GTK_WINDOW (l->data);
GtkRequisition req;
- if (nw2 != nw) {
+ if (nw == NULL || nw2 != nw) {
gtk_widget_size_request (GTK_WIDGET (nw2), &req);
translate_coordinates (stack->location,
@@ -312,7 +315,7 @@ notify_stack_shift_notifications (NotifyStack *stack,
for (i = n_wins - 1, l = g_list_last (stack->windows); l != NULL; i--, l = l->prev) {
GtkWindow *nw2 = GTK_WINDOW (l->data);
- if (nw2 != nw) {
+ if (nw == NULL || nw2 != nw) {
theme_move_notification (nw2, positions[i].x, positions[i].y);
}
}
@@ -320,6 +323,37 @@ notify_stack_shift_notifications (NotifyStack *stack,
g_free (positions);
}
+static void
+update_position (NotifyStack *stack)
+{
+ notify_stack_shift_notifications (stack,
+ NULL, /* window */
+ NULL, /* list pointer */
+ 0, /* init width */
+ 0, /* init height */
+ NULL, /* out window x */
+ NULL); /* out window y */
+}
+
+static gboolean
+update_position_idle (NotifyStack *stack)
+{
+ update_position (stack);
+
+ stack->update_id = 0;
+ return FALSE;
+}
+
+void
+notify_stack_queue_update_position (NotifyStack *stack)
+{
+ if (stack->update_id != 0) {
+ return;
+ }
+
+ stack->update_id = g_idle_add ((GSourceFunc) update_position_idle, stack);
+}
+
void
notify_stack_add_window (NotifyStack *stack,
GtkWindow *nw,
diff --git a/src/daemon/stack.h b/src/daemon/stack.h
index cc043a2..f9f9172 100644
--- a/src/daemon/stack.h
+++ b/src/daemon/stack.h
@@ -52,5 +52,6 @@ void notify_stack_add_window (NotifyStack *stack,
void notify_stack_remove_window (NotifyStack *stack,
GtkWindow *nw);
GList * notify_stack_get_windows (NotifyStack *stack);
+void notify_stack_queue_update_position (NotifyStack *stack);
#endif /* _NOTIFY_STACK_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]