diff options
author | Ray Strode <rstrode@redhat.com> | 2007-04-18 09:57:58 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2007-04-18 09:57:58 -0400 |
commit | 984354cce83e152dcef6b6cef0f5c80988563ec4 (patch) | |
tree | 23a3774e8460dc1b7e14719c47575e7389241ed7 | |
parent | fac22f053b37386dd13152f9063cde817a466aa8 (diff) |
Start to move code over to PopXReplyWatch instead of
gdk_error_trap_push/gdk_error_trap_pop
-rw-r--r-- | src/pop-demo.c | 17 | ||||
-rw-r--r-- | src/pop-window-stack.c | 207 | ||||
-rw-r--r-- | src/pop-window-stack.h | 6 | ||||
-rw-r--r-- | src/pop-x-reply-watch.c | 3 |
4 files changed, 176 insertions, 57 deletions
diff --git a/src/pop-demo.c b/src/pop-demo.c index 96f687e..c7fa5cb 100644 --- a/src/pop-demo.c +++ b/src/pop-demo.c @@ -96,6 +96,23 @@ remove_window_from_list (GdkWindow *window) g_object_unref (G_OBJECT (window)); } +static Status +query_tree_request (GdkDisplay *display, + gpointer data) +{ + GdkWindow *window; + Window parent, root, *children; + guint number_of_children, i; + gboolean tree_queried; + + window = GDK_WINDOW (data); + g_assert (GDK_IS_WINDOW (window)); + + return XQueryTree (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XWINDOW (window), + &root, &parent, &children, &number_of_children); +} + static void add_window_to_list (GdkWindow *window) { diff --git a/src/pop-window-stack.c b/src/pop-window-stack.c index 8ad0320..397a932 100644 --- a/src/pop-window-stack.c +++ b/src/pop-window-stack.c @@ -31,12 +31,15 @@ #include <gdk/gdk.h> #include "pop-event-listener.h" +#include "pop-x-reply-watch.h" struct _PopWindowStackPrivate { GdkScreen *screen; PopEventListener *event_listener; GQueue *windows; + + guint32 is_ready : 1; }; typedef struct @@ -59,28 +62,28 @@ static void pop_window_stack_finalize (GObject * object); static void pop_window_stack_class_install_signals (PopWindowStackClass * stack_class); #endif -static void pop_window_stack_class_install_properties (PopWindowStackClass * - stack_class); - -static void pop_window_stack_set_property (GObject * object, - guint prop_id, - const GValue * value, - GParamSpec * pspec); -static void pop_window_stack_get_property (GObject * object, - guint prop_id, - GValue * value, - GParamSpec * pspec); +static void pop_window_stack_class_install_properties (PopWindowStackClass *stack_class); + +static void pop_window_stack_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void pop_window_stack_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); static void pop_window_stack_set_screen (PopWindowStack *stack, GdkScreen *screen); static void pop_window_stack_clear_window_list (PopWindowStack *stack); -static void pop_window_stack_get_initial_window_list (PopWindowStack *stack); +static void pop_window_stack_ask_for_window_list (PopWindowStack *stack); enum { PROP_0 = 0, - PROP_SCREEN + PROP_SCREEN, + PROP_IS_READY }; #if 0 @@ -143,6 +146,13 @@ pop_window_stack_class_install_properties (PopWindowStackClass * stack_class) _("Which screen to user for tracking window stack"), G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_SCREEN, param_spec); + + param_spec = g_param_spec_boolean ("is-ready", _("Is it ready?"), + _("whether or not the window stack is fully " + "initialized and can be used"), FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_IS_READY, param_spec); + } static void @@ -155,18 +165,20 @@ pop_window_stack_init (PopWindowStack *stack) stack->priv->event_listener = pop_event_listener_get_default (); g_signal_connect_swapped (G_OBJECT (stack->priv->event_listener), "window-layered-under", - G_CALLBACK (pop_window_stack_get_initial_window_list), + G_CALLBACK (pop_window_stack_ask_for_window_list), stack); g_signal_connect_swapped (G_OBJECT (stack->priv->event_listener), "window-layered-on-top", - G_CALLBACK (pop_window_stack_get_initial_window_list), + G_CALLBACK (pop_window_stack_ask_for_window_list), stack); g_signal_connect_swapped (G_OBJECT (stack->priv->event_listener), "window-layered-on-bottom", - G_CALLBACK (pop_window_stack_get_initial_window_list), + G_CALLBACK (pop_window_stack_ask_for_window_list), stack); stack->priv->windows = g_queue_new (); + + stack->priv->is_ready = FALSE; } static void @@ -189,9 +201,10 @@ pop_window_stack_finalize (GObject * object) } static void -pop_window_stack_set_property (GObject * object, - guint prop_id, - const GValue * value, GParamSpec * pspec) +pop_window_stack_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { PopWindowStack *stack = POP_WINDOW_STACK (object); @@ -200,6 +213,9 @@ pop_window_stack_set_property (GObject * object, case PROP_SCREEN: pop_window_stack_set_screen (stack, g_value_get_pointer (value)); break; + case POP_IS_READY: + pop_window_stack_set_readiness (stack, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -219,6 +235,10 @@ pop_window_stack_get_property (GObject * object, g_value_set_pointer (value, stack->priv->screen); break; + case POP_IS_READY: + g_value_set_boolean (value, stack->priv->is_ready); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -275,6 +295,14 @@ pop_window_stack_get_for_screen (GdkScreen *screen) return g_object_ref (stack); } +gboolean +pop_window_stack_is_ready (PopWindowStack *stack) +{ + g_return_val_if_fail (POP_IS_WINDOW_STACK (stack), FALSE); + + return stack->priv->is_ready; +} + guint pop_window_stack_get_length (PopWindowStack *stack) { @@ -305,6 +333,7 @@ pop_window_stack_foreach (PopWindowStack *stack, g_return_if_fail (POP_IS_WINDOW_STACK (stack)); g_return_if_fail (func != NULL); + g_return_if_fail (pop_window_stack_is_ready (stack)); closure.stack = stack; closure.func = func; @@ -338,6 +367,7 @@ pop_window_stack_above_window_foreach (PopWindowStack *sta g_return_if_fail (POP_IS_WINDOW_STACK (stack)); g_return_if_fail (func != NULL); g_return_if_fail (window != NULL); + g_return_if_fail (pop_window_stack_is_ready (stack)); window_link = g_queue_find (stack->priv->windows, window); @@ -360,6 +390,9 @@ pop_window_stack_above_window_foreach (PopWindowStack *sta static void pop_window_stack_clear_window_list (PopWindowStack *stack) { + + pop_window_stack_set_readiness (stack, FALSE); + if (g_queue_is_empty (stack->priv->windows)) return; @@ -389,14 +422,94 @@ window_can_output (GdkWindow *window) return attrs.class == InputOutput; } +typedef struct +{ + GdkWindow *window; + Window *children; + guint number_of_children; +} PopQueryTreeState; + +static Status +query_tree_request (GdkDisplay *display, + gpointer data) +{ + Window parent, root; + PopQueryTreeState *state; + + g_assert (state != NULL); + state = (PopQueryTreeState *) state; + + g_assert (GDK_IS_WINDOW (state->window)); + + return XQueryTree (GDK_DISPLAY_XDISPLAY (display), + GDK_WINDOW_XWINDOW (state->window), + &root, &parent, &state->children, + &state->number_of_children); +} + static void -pop_window_stack_get_initial_window_list (PopWindowStack *stack) +queried_window_foreach_func (Window window, + gpointer data) +{ + PopWindowStack *stack; + GdkWindow *window; + + g_assert (POP_IS_WINDOW_STACK (data)); + stack = POP_WINDOW_STACK (data); + + window = gdk_window_foreign_new_for_display (display, children[i]); + + if (window == NULL) + return; + + if (!window_can_output (window)) + { + g_print ("excluding window 0x%lx\n", GDK_WINDOW_XWINDOW (window)); + g_object_unref (window); + return; + } + + g_queue_push_tail (stack->priv->windows, window); +} + +static void +on_query_tree_reply (GdkDisplay *display, + Status tree_queried, + XErrorEvent *error, + gpointer user_data) +{ + PopQueryTreeState *state; + + g_assert (state != NULL); + state = (PopQueryTreeState *) state; + + if (tree_queried) + { + guint i; + g_assert (state->number_of_children > 0); + g_assert (state->children != NULL); + + for (i = 0; i < number_of_children; i++) + queried_window_foreach_func (state->children[i], stack); + + XFree (state->children); + state->children = NULL; + state->number_of_children = 0; + } + + g_object_unref (state->window); + state->window = NULL; + g_slice_free (PopQueryTreeState, state); + + pop_window_stack_set_readiness (stack, TRUE); +} + +static void +pop_window_stack_ask_for_window_list (PopWindowStack *stack) { GdkScreen *screen; GdkDisplay *display; - Window root, parent, *children; - guint number_of_children, i; - gboolean query_was_successful; + PopQueryTreeState *state; pop_window_stack_clear_window_list (stack); @@ -407,35 +520,12 @@ pop_window_stack_get_initial_window_list (PopWindowStack *stack) display = gdk_screen_get_display (screen); - gdk_x11_display_grab (display); - query_was_successful = - XQueryTree (GDK_DISPLAY_XDISPLAY (display), - GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen)), - &root, &parent, &children, &number_of_children); - - if (query_was_successful) - { - for (i = 0; i < number_of_children; i++) - { - GdkWindow *window; - - window = gdk_window_foreign_new_for_display (display, children[i]); - - if (window == NULL) - continue; - - if (!window_can_output (window)) - { - g_print ("excluding window 0x%lx\n", GDK_WINDOW_XWINDOW (window)); - g_object_unref (window); - continue; - } + state = g_slice_new0 (PopQueryTreeState); + state->window = g_object_ref (gdk_screen_get_root_window (screen)); - g_queue_push_tail (stack->priv->windows, window); - } - XFree (children); - } - gdk_x11_display_ungrab (display); + pop_x_reply_watch_add (display, + query_tree_request, state, + on_query_tree_reply, state); } static void @@ -445,11 +535,24 @@ pop_window_stack_set_screen (PopWindowStack *stack, if (screen != stack->priv->screen) { stack->priv->screen = screen; - pop_window_stack_get_initial_window_list (stack); + pop_window_stack_ask_for_window_list (stack); g_object_notify (G_OBJECT (stack), "screen"); } } +static void +pop_window_stack_set_readiness (PopWindowStack *stack, + gboolean is_ready) +{ + is_ready = (is_ready == TRUE); + + if (is_ready != stack->priv->is_ready) + { + stack->priv->is_ready = is_ready; + g_object_notify (G_OBJECT (stack), "is-ready"); + } +} + #ifdef POP_WINDOW_STACK_ENABLE_TEST #include <stdio.h> diff --git a/src/pop-window-stack.h b/src/pop-window-stack.h index d8e7803..60c5819 100644 --- a/src/pop-window-stack.h +++ b/src/pop-window-stack.h @@ -51,11 +51,6 @@ struct _PopWindowStack struct _PopWindowStackClass { GObjectClass parent_class; - - /* signals */ -#if 0 - void (*foo) (PopWindowStack * stack); -#endif }; enum _PopWindowStackError @@ -68,6 +63,7 @@ GType pop_window_stack_get_type (void); GQuark pop_window_stack_error_quark (void); PopWindowStack *pop_window_stack_get_for_screen (GdkScreen *screen); +gboolean pop_window_stack_is_ready (PopWindowStack *stack); guint pop_window_stack_get_length (PopWindowStack *stack); void pop_window_stack_foreach (PopWindowStack *stack, PopWindowStackForeachFunc func, diff --git a/src/pop-x-reply-watch.c b/src/pop-x-reply-watch.c index 9a34bb3..1ab987b 100644 --- a/src/pop-x-reply-watch.c +++ b/src/pop-x-reply-watch.c @@ -56,6 +56,9 @@ pop_x_reply_watch_check (GSource *source) gulong last_processed_request_id; PopXReplyWatchSource *x_reply_watch_source; + /* FIXME: add a poll fd to prevent spurious wakeups? + */ + x_reply_watch_source = (PopXReplyWatchSource *) source; last_processed_request_id = LastKnownRequestProcessed (GDK_DISPLAY_XDISPLAY (x_reply_watch_source->display)); |