summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2007-04-18 09:57:58 -0400
committerRay Strode <rstrode@redhat.com>2007-04-18 09:57:58 -0400
commit984354cce83e152dcef6b6cef0f5c80988563ec4 (patch)
tree23a3774e8460dc1b7e14719c47575e7389241ed7
parentfac22f053b37386dd13152f9063cde817a466aa8 (diff)
Start to move code over to PopXReplyWatch instead of
gdk_error_trap_push/gdk_error_trap_pop
-rw-r--r--src/pop-demo.c17
-rw-r--r--src/pop-window-stack.c207
-rw-r--r--src/pop-window-stack.h6
-rw-r--r--src/pop-x-reply-watch.c3
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));