*/
/*
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * Modified by the GTK+ Team and others 1997-2007. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include <config.h>
+
#include "gdk.h"
#include "gdkprivate-x11.h"
#include "gdkinternals.h"
#include "gdkx.h"
#include "gdkscreen-x11.h"
#include "gdkdisplay-x11.h"
+#include "gdkasync.h"
#include "gdkkeysyms.h"
#include "xsettings-client.h"
-#if HAVE_CONFIG_H
-# include <config.h>
-# if STDC_HEADERS
-# include <string.h>
-# endif
-#endif
+#include <string.h>
#include "gdkinputprivate.h"
+#include "gdksettings.c"
+#include "gdkalias.h"
+
#ifdef HAVE_XKB
#include <X11/XKBlib.h>
#endif
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
#include <X11/Xatom.h>
typedef struct _GdkIOClosure GdkIOClosure;
typedef struct _GdkDisplaySource GdkDisplaySource;
-
-#define DOUBLE_CLICK_TIME 250
-#define TRIPLE_CLICK_TIME 500
-#define DOUBLE_CLICK_DIST 5
-#define TRIPLE_CLICK_DIST 5
+typedef struct _GdkEventTypeX11 GdkEventTypeX11;
struct _GdkIOClosure
{
GPollFD event_poll_fd;
};
+struct _GdkEventTypeX11
+{
+ gint base;
+ gint n_events;
+};
+
/*
* Private function declarations
*/
* Functions for maintaining the event queue *
*********************************************/
+static void
+refcounted_grab_server (Display *xdisplay)
+{
+ GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
+
+ gdk_x11_display_grab (display);
+}
+
+static void
+refcounted_ungrab_server (Display *xdisplay)
+{
+ GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
+
+ gdk_x11_display_ungrab (display);
+}
+
void
_gdk_x11_events_init_screen (GdkScreen *screen)
{
/* Keep a flag to avoid extra notifies that we don't need
*/
screen_x11->xsettings_in_init = TRUE;
- screen_x11->xsettings_client = xsettings_client_new (screen_x11->xdisplay,
- screen_x11->screen_num,
- gdk_xsettings_notify_cb,
- gdk_xsettings_watch_cb,
- screen);
+ screen_x11->xsettings_client = xsettings_client_new_with_grab_funcs (screen_x11->xdisplay,
+ screen_x11->screen_num,
+ gdk_xsettings_notify_cb,
+ gdk_xsettings_watch_cb,
+ screen,
+ refcounted_grab_server,
+ refcounted_ungrab_server);
screen_x11->xsettings_in_init = FALSE;
}
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
- xsettings_client_destroy (screen_x11->xsettings_client);
- screen_x11->xsettings_client = NULL;
+ if (screen_x11->xsettings_client)
+ {
+ xsettings_client_destroy (screen_x11->xsettings_client);
+ screen_x11->xsettings_client = NULL;
+ }
}
void
display_sources = g_list_prepend (display_sources,display_source);
- gdk_display_add_client_message_filter (
- display,
- gdk_atom_intern ("WM_PROTOCOLS", FALSE),
- gdk_wm_protocols_filter,
- NULL);
+ gdk_display_add_client_message_filter (display,
+ gdk_atom_intern_static_string ("WM_PROTOCOLS"),
+ gdk_wm_protocols_filter,
+ NULL);
}
+void
+_gdk_events_uninit (GdkDisplay *display)
+{
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+
+ if (display_x11->event_source)
+ {
+ display_sources = g_list_remove (display_sources,
+ display_x11->event_source);
+ g_source_destroy (display_x11->event_source);
+ g_source_unref (display_x11->event_source);
+ display_x11->event_source = NULL;
+ }
+}
/**
* gdk_events_pending:
*
* Adds a filter to be called when X ClientMessage events are received.
*
+ * Since: 2.2
**/
void
gdk_display_add_client_message_filter (GdkDisplay *display,
filter->data = data;
GDK_DISPLAY_X11(display)->client_filters =
- g_list_prepend (GDK_DISPLAY_X11 (display)->client_filters,
- filter);
+ g_list_append (GDK_DISPLAY_X11 (display)->client_filters,
+ filter);
}
/**
}
static void
-gdk_check_wm_state_changed (GdkWindow *window)
-{
- Atom type;
- gint format;
- gulong nitems;
- gulong bytes_after;
- Atom *atoms = NULL;
- gulong i;
- gboolean found_sticky, found_maxvert, found_maxhorz, found_fullscreen;
+do_net_wm_state_changes (GdkWindow *window)
+{
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
GdkWindowState old_state;
- GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
if (GDK_WINDOW_DESTROYED (window) ||
gdk_window_get_window_type (window) != GDK_WINDOW_TOPLEVEL)
return;
- found_sticky = FALSE;
- found_maxvert = FALSE;
- found_maxhorz = FALSE;
- found_fullscreen = FALSE;
-
- XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
- gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
- 0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
- &bytes_after, (guchar **)&atoms);
-
- if (type != None)
- {
- Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
- Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
- Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
- Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
-
- i = 0;
- while (i < nitems)
- {
- if (atoms[i] == sticky_atom)
- found_sticky = TRUE;
- else if (atoms[i] == maxvert_atom)
- found_maxvert = TRUE;
- else if (atoms[i] == maxhorz_atom)
- found_maxhorz = TRUE;
- else if (atoms[i] == fullscreen_atom)
- found_fullscreen = TRUE;
-
- ++i;
- }
-
- XFree (atoms);
- }
+ old_state = gdk_window_get_state (window);
/* For found_sticky to remain TRUE, we have to also be on desktop
* 0xFFFFFFFF
*/
-
- if (found_sticky)
- {
- gulong *desktop;
-
- XGetWindowProperty (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- gdk_x11_get_xatom_by_name_for_display
- (display, "_NET_WM_DESKTOP"),
- 0, G_MAXLONG, False, XA_CARDINAL, &type,
- &format, &nitems,
- &bytes_after, (guchar **)&desktop);
-
- if (type != None)
- {
- if (*desktop != 0xFFFFFFFF)
- found_sticky = FALSE;
- XFree (desktop);
- }
- }
-
- old_state = gdk_window_get_state (window);
-
if (old_state & GDK_WINDOW_STATE_STICKY)
{
- if (!found_sticky)
+ if (!(toplevel->have_sticky && toplevel->on_all_desktops))
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_STICKY,
0);
}
else
{
- if (found_sticky)
+ if (toplevel->have_sticky || toplevel->on_all_desktops)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_STICKY);
if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
{
- if (!found_fullscreen)
+ if (!toplevel->have_fullscreen)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_FULLSCREEN,
0);
}
else
{
- if (found_fullscreen)
+ if (toplevel->have_fullscreen)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_FULLSCREEN);
*/
if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
{
- if (!(found_maxvert && found_maxhorz))
+ if (!(toplevel->have_maxvert && toplevel->have_maxhorz))
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_MAXIMIZED,
0);
}
else
{
- if (found_maxvert && found_maxhorz)
+ if (toplevel->have_maxvert && toplevel->have_maxhorz)
gdk_synthesize_window_state (window,
0,
GDK_WINDOW_STATE_MAXIMIZED);
}
}
-#define HAS_FOCUS(window_impl) \
- ((window_impl)->has_focus || (window_impl)->has_pointer_focus)
+static void
+gdk_check_wm_desktop_changed (GdkWindow *window)
+{
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ gulong *desktop;
+
+ type = None;
+ gdk_error_trap_push ();
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
+ 0, G_MAXLONG, False, XA_CARDINAL, &type,
+ &format, &nitems,
+ &bytes_after, &data);
+ gdk_error_trap_pop ();
+
+ if (type != None)
+ {
+ desktop = (gulong *)data;
+ toplevel->on_all_desktops = (*desktop == 0xFFFFFFFF);
+ XFree (desktop);
+ }
+ else
+ toplevel->on_all_desktops = FALSE;
+
+ do_net_wm_state_changes (window);
+}
+
+static void
+gdk_check_wm_state_changed (GdkWindow *window)
+{
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ Atom *atoms = NULL;
+ gulong i;
+
+ gboolean had_sticky = toplevel->have_sticky;
+
+ toplevel->have_sticky = FALSE;
+ toplevel->have_maxvert = FALSE;
+ toplevel->have_maxhorz = FALSE;
+ toplevel->have_fullscreen = FALSE;
+
+ type = None;
+ gdk_error_trap_push ();
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ 0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
+ &bytes_after, &data);
+ gdk_error_trap_pop ();
+
+ if (type != None)
+ {
+ Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
+ Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
+ Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
+ Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
+
+ atoms = (Atom *)data;
+
+ i = 0;
+ while (i < nitems)
+ {
+ if (atoms[i] == sticky_atom)
+ toplevel->have_sticky = TRUE;
+ else if (atoms[i] == maxvert_atom)
+ toplevel->have_maxvert = TRUE;
+ else if (atoms[i] == maxhorz_atom)
+ toplevel->have_maxhorz = TRUE;
+ else if (atoms[i] == fullscreen_atom)
+ toplevel->have_fullscreen = TRUE;
+
+ ++i;
+ }
+
+ XFree (atoms);
+ }
+
+ /* When have_sticky is turned on, we have to check the DESKTOP property
+ * as well.
+ */
+ if (toplevel->have_sticky && !had_sticky)
+ gdk_check_wm_desktop_changed (window);
+ else
+ do_net_wm_state_changes (window);
+}
+
+#define HAS_FOCUS(toplevel) \
+ ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
static void
generate_focus_event (GdkWindow *window,
gdk_event_put (&event);
}
-static void
+static gboolean
set_screen_from_root (GdkDisplay *display,
GdkEvent *event,
Window xrootwin)
GdkScreen *screen;
screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
- g_assert (screen);
- gdk_event_set_screen (event, screen);
+ if (screen)
+ {
+ gdk_event_set_screen (event, screen);
+
+ return TRUE;
+ }
+
+ return FALSE;
}
static void
{
GdkKeymap *keymap = gdk_keymap_get_for_display (display);
gunichar c = 0;
- guchar buf[7];
+ gchar buf[7];
event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
event->key.time = xevent->xkey.time;
&event->key.keyval,
NULL, NULL, NULL);
+ _gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
+ event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
+
/* Fill in event->string crudely, since various programs
* depend on it.
*/
event->key.length, buf);
}
#endif /* G_ENABLE_DEBUG */
+ return;
+}
+
+/**
+ * gdk_x11_register_standard_event_type:
+ * @display: a #GdkDisplay
+ * @event_base: first event type code to register
+ * @n_events: number of event type codes to register
+ *
+ * Registers interest in receiving extension events with type codes
+ * between @event_base and <literal>event_base + n_events - 1</literal>.
+ * The registered events must have the window field in the same place
+ * as core X events (this is not the case for e.g. XKB extension events).
+ *
+ * If an event type is registered, events of this type will go through
+ * global and window-specific filters (see gdk_window_add_filter()).
+ * Unregistered events will only go through global filters.
+ * GDK may register the events of some X extensions on its own.
+ *
+ * This function should only be needed in unusual circumstances, e.g.
+ * when filtering XInput extension events on the root window.
+ *
+ * Since: 2.4
+ **/
+void
+gdk_x11_register_standard_event_type (GdkDisplay *display,
+ gint event_base,
+ gint n_events)
+{
+ GdkEventTypeX11 *event_type;
+ GdkDisplayX11 *display_x11;
+
+ display_x11 = GDK_DISPLAY_X11 (display);
+ event_type = g_new (GdkEventTypeX11, 1);
+
+ event_type->base = event_base;
+ event_type->n_events = n_events;
+
+ display_x11->event_types = g_slist_prepend (display_x11->event_types, event_type);
}
/* Return the window this has to do with, if any, rather
* than the frame or root window that was selecting
* for substructure
*/
-static Window
-get_real_window (XEvent *event)
+static void
+get_real_window (GdkDisplay *display,
+ XEvent *event,
+ Window *event_window,
+ Window *filter_window)
{
- switch (event->type)
- {
- case CreateNotify:
- return event->xcreatewindow.window;
-
- case DestroyNotify:
- return event->xdestroywindow.window;
-
- case UnmapNotify:
- return event->xunmap.window;
+ /* Core events all have an event->xany.window field, but that's
+ * not true for extension events
+ */
+ if (event->type >= KeyPress &&
+ event->type <= MappingNotify)
+ {
+ *filter_window = event->xany.window;
+ switch (event->type)
+ {
+ case CreateNotify:
+ *event_window = event->xcreatewindow.window;
+ break;
+ case DestroyNotify:
+ *event_window = event->xdestroywindow.window;
+ break;
+ case UnmapNotify:
+ *event_window = event->xunmap.window;
+ break;
+ case MapNotify:
+ *event_window = event->xmap.window;
+ break;
+ case MapRequest:
+ *event_window = event->xmaprequest.window;
+ break;
+ case ReparentNotify:
+ *event_window = event->xreparent.window;
+ break;
+ case ConfigureNotify:
+ *event_window = event->xconfigure.window;
+ break;
+ case ConfigureRequest:
+ *event_window = event->xconfigurerequest.window;
+ break;
+ case GravityNotify:
+ *event_window = event->xgravity.window;
+ break;
+ case CirculateNotify:
+ *event_window = event->xcirculate.window;
+ break;
+ case CirculateRequest:
+ *event_window = event->xcirculaterequest.window;
+ break;
+ default:
+ *event_window = event->xany.window;
+ }
+ }
+ else
+ {
+ GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
+ GSList *tmp_list;
- case MapNotify:
- return event->xmap.window;
+ for (tmp_list = display_x11->event_types;
+ tmp_list;
+ tmp_list = tmp_list->next)
+ {
+ GdkEventTypeX11 *event_type = tmp_list->data;
- case MapRequest:
- return event->xmaprequest.window;
+ if (event->type >= event_type->base &&
+ event->type < event_type->base + event_type->n_events)
+ {
+ *event_window = event->xany.window;
+ *filter_window = event->xany.window;
+ return;
+ }
+ }
+
+ *event_window = None;
+ *filter_window = None;
+ }
+}
- case ReparentNotify:
- return event->xreparent.window;
-
- case ConfigureNotify:
- return event->xconfigure.window;
-
- case ConfigureRequest:
- return event->xconfigurerequest.window;
+#ifdef G_ENABLE_DEBUG
+static const char notify_modes[][19] = {
+ "NotifyNormal",
+ "NotifyGrab",
+ "NotifyUngrab",
+ "NotifyWhileGrabbed"
+};
- case GravityNotify:
- return event->xgravity.window;
+static const char notify_details[][23] = {
+ "NotifyAncestor",
+ "NotifyVirtual",
+ "NotifyInferior",
+ "NotifyNonlinear",
+ "NotifyNonlinearVirtual",
+ "NotifyPointer",
+ "NotifyPointerRoot",
+ "NotifyDetailNone"
+};
+#endif
- case CirculateNotify:
- return event->xcirculate.window;
+static void
+set_user_time (GdkWindow *window,
+ GdkEvent *event)
+{
+ g_return_if_fail (event != NULL);
- case CirculateRequest:
- return event->xcirculaterequest.window;
+ window = gdk_window_get_toplevel (event->client.window);
+ g_return_if_fail (GDK_IS_WINDOW (window));
- default:
- return event->xany.window;
- }
+ /* If an event doesn't have a valid timestamp, we shouldn't use it
+ * to update the latest user interaction time.
+ */
+ if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
}
static gboolean
GdkWindow *window;
GdkWindowObject *window_private;
+ GdkWindow *filter_window;
GdkWindowImplX11 *window_impl = NULL;
- gint return_val;
+ gboolean return_val;
gint xoffset, yoffset;
GdkScreen *screen = NULL;
GdkScreenX11 *screen_x11 = NULL;
+ GdkToplevelX11 *toplevel = NULL;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
- Window xwindow;
+ Window xwindow, filter_xwindow;
return_val = FALSE;
}
}
- /* We handle events with window=None
- * specially - they are generated by XFree86's XInput under
- * some circumstances. This handling for obvious reasons
- * goes before we bother to lookup the event window.
- */
-
- if (xevent->xany.window == None)
- {
- return_val = _gdk_input_window_none_event (event, xevent);
-
- if (return_val >= 0) /* was handled */
- return return_val;
- else
- return_val = FALSE;
- }
-
/* Find the GdkWindow that this event relates to.
* Basically this means substructure events
* are reported same as structure events
*/
- xwindow = get_real_window (xevent);
+ get_real_window (display, xevent, &xwindow, &filter_xwindow);
window = gdk_window_lookup_for_display (display, xwindow);
+ /* We may receive events such as NoExpose/GraphicsExpose
+ * and ShmCompletion for pixmaps
+ */
+ if (window && !GDK_IS_WINDOW (window))
+ window = NULL;
window_private = (GdkWindowObject *) window;
+ /* We always run the filters for the window where the event
+ * is delivered, not the window that it relates to
+ */
+ if (filter_xwindow == xwindow)
+ filter_window = window;
+ else
+ {
+ filter_window = gdk_window_lookup_for_display (display, filter_xwindow);
+ if (filter_window && !GDK_IS_WINDOW (filter_window))
+ filter_window = NULL;
+ }
+
if (window)
{
screen = GDK_WINDOW_SCREEN (window);
screen_x11 = GDK_SCREEN_X11 (screen);
+ toplevel = _gdk_x11_window_get_toplevel (window);
}
if (window != NULL)
{
- /* Window may be a pixmap, so check its type.
- * (This check is probably too expensive unless
- * GLib short-circuits an exact type match,
- * which has been proposed)
- */
- if (GDK_IS_WINDOW (window))
- {
- window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
-
- /* Move key events on focus window to the real toplevel, and
- * filter out all other events on focus window
- */
- if (xwindow == window_impl->focus_window)
- {
- switch (xevent->type)
- {
- case KeyPress:
- case KeyRelease:
- xwindow = GDK_WINDOW_XID (window);
- xevent->xany.window = xwindow;
- break;
- default:
- return FALSE;
- }
- }
- }
+ window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
+
+ /* Move key events on focus window to the real toplevel, and
+ * filter out all other events on focus window
+ */
+ if (toplevel && xwindow == toplevel->focus_window)
+ {
+ switch (xevent->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ xwindow = GDK_WINDOW_XID (window);
+ xevent->xany.window = xwindow;
+ break;
+ default:
+ return FALSE;
+ }
+ }
g_object_ref (window);
}
goto done;
}
}
- else if (window_private)
+ else if (filter_window)
{
/* Apply per-window filters */
+ GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
GdkFilterReturn result;
- result = gdk_event_apply_filters (xevent, event,
- window_private->filters);
-
- if (result != GDK_FILTER_CONTINUE)
+
+ if (filter_private->filters)
{
- return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
- goto done;
+ g_object_ref (filter_window);
+
+ result = gdk_event_apply_filters (xevent, event,
+ filter_private->filters);
+
+ g_object_unref (filter_window);
+
+ if (result != GDK_FILTER_CONTINUE)
+ {
+ return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+ goto done;
+ }
}
}
break;
}
translate_key_event (display, event, xevent);
+ set_user_time (window, event);
break;
case KeyRelease:
event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
event->scroll.state = (GdkModifierType) xevent->xbutton.state;
event->scroll.device = display->core_pointer;
-
- set_screen_from_root (display, event, xevent->xbutton.root);
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
break;
event->button.button = xevent->xbutton.button;
event->button.device = display->core_pointer;
- set_screen_from_root (display, event, xevent->xbutton.root);
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
_gdk_event_button_generate (display, event);
break;
}
+ set_user_time (window, event);
+
+ _gdk_xgrab_check_button_event (window, xevent);
break;
case ButtonRelease:
event->button.button = xevent->xbutton.button;
event->button.device = display->core_pointer;
- set_screen_from_root (display, event, xevent->xbutton.root);
-
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ _gdk_xgrab_check_button_event (window, xevent);
break;
case MotionNotify:
return_val = FALSE;
break;
}
-
+
event->motion.type = GDK_MOTION_NOTIFY;
event->motion.window = window;
event->motion.time = xevent->xmotion.time;
event->motion.is_hint = xevent->xmotion.is_hint;
event->motion.device = display->core_pointer;
- set_screen_from_root (display, event, xevent->xmotion.root);
-
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
break;
case EnterNotify:
break;
}
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
/* Handle focusing (in the case where no window manager is running */
- if (window &&
- GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
- xevent->xcrossing.detail != NotifyInferior &&
- xevent->xcrossing.focus && !window_impl->has_focus)
+ if (toplevel && xevent->xcrossing.detail != NotifyInferior)
{
- gboolean had_focus = HAS_FOCUS (window_impl);
-
- window_impl->has_pointer_focus = TRUE;
+ toplevel->has_pointer = TRUE;
- if (HAS_FOCUS (window_impl) != had_focus)
- generate_focus_event (window, TRUE);
+ if (xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = TRUE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, TRUE);
+ }
}
/* Tell XInput stuff about it if appropriate */
event->crossing.x_root = xevent->xcrossing.x_root;
event->crossing.y_root = xevent->xcrossing.y_root;
- set_screen_from_root (display, event, xevent->xcrossing.root);
-
/* Translate the crossing mode into Gdk terms.
*/
switch (xevent->xcrossing.mode)
return_val = FALSE;
break;
}
-
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
/* Handle focusing (in the case where no window manager is running */
- if (window &&
- GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
- xevent->xcrossing.detail != NotifyInferior &&
- xevent->xcrossing.focus && !window_impl->has_focus)
+ if (toplevel && xevent->xcrossing.detail != NotifyInferior)
{
- gboolean had_focus = HAS_FOCUS (window_impl);
-
- window_impl->has_pointer_focus = FALSE;
+ toplevel->has_pointer = FALSE;
- if (HAS_FOCUS (window_impl) != had_focus)
- generate_focus_event (window, FALSE);
+ if (xevent->xcrossing.focus && !toplevel->has_focus_window)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ toplevel->has_pointer_focus = FALSE;
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (window, FALSE);
+ }
}
event->crossing.type = GDK_LEAVE_NOTIFY;
event->crossing.x_root = xevent->xcrossing.x_root;
event->crossing.y_root = xevent->xcrossing.y_root;
- set_screen_from_root (display, event, xevent->xcrossing.root);
-
/* Translate the crossing mode into Gdk terms.
*/
switch (xevent->xcrossing.mode)
*/
case FocusIn:
GDK_NOTE (EVENTS,
- g_message ("focus in:\t\twindow: %ld", xevent->xfocus.window));
+ g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
- if (window && GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
+ if (toplevel)
{
- gboolean had_focus = HAS_FOCUS (window_impl);
+ gboolean had_focus = HAS_FOCUS (toplevel);
switch (xevent->xfocus.detail)
{
case NotifyAncestor:
- case NotifyNonlinear:
case NotifyVirtual:
+ /* When the focus moves from an ancestor of the window to
+ * the window or a descendent of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_pointer_focus
+ * case and are now receiving them in the
+ * has_focus_window case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+
+ /* fall through */
+ case NotifyNonlinear:
case NotifyNonlinearVirtual:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = TRUE;
/* We pretend that the focus moves to the grab
* window, so we pay attention to NotifyGrab
* NotifyUngrab, and ignore NotifyWhileGrabbed
*/
if (xevent->xfocus.mode != NotifyWhileGrabbed)
- window_impl->has_focus = TRUE;
+ toplevel->has_focus = TRUE;
break;
case NotifyPointer:
/* The X server sends NotifyPointer/NotifyGrab,
* but the pointer focus is ignored while a
* grab is in effect
*/
- if (xevent->xfocus.mode != NotifyGrab)
- window_impl->has_pointer_focus = TRUE;
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
break;
case NotifyInferior:
case NotifyPointerRoot:
break;
}
- if (HAS_FOCUS (window_impl) != had_focus)
+ if (HAS_FOCUS (toplevel) != had_focus)
generate_focus_event (window, TRUE);
}
break;
case FocusOut:
GDK_NOTE (EVENTS,
- g_message ("focus out:\t\twindow: %ld", xevent->xfocus.window));
-
- if (window && GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
+ g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
{
- gboolean had_focus = HAS_FOCUS (window_impl);
+ gboolean had_focus = HAS_FOCUS (toplevel);
switch (xevent->xfocus.detail)
{
case NotifyAncestor:
- case NotifyNonlinear:
case NotifyVirtual:
+ /* When the focus moves from the window or a descendent
+ * of the window to an ancestor of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_focus_window
+ * case and are now receiving them in the
+ * has_pointer_focus case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
+
+ /* fall through */
+ case NotifyNonlinear:
case NotifyNonlinearVirtual:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = FALSE;
if (xevent->xfocus.mode != NotifyWhileGrabbed)
- window_impl->has_focus = FALSE;
+ toplevel->has_focus = FALSE;
break;
case NotifyPointer:
- if (xevent->xfocus.mode != NotifyUngrab)
- window_impl->has_pointer_focus = FALSE;
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
break;
case NotifyInferior:
case NotifyPointerRoot:
break;
}
- if (HAS_FOCUS (window_impl) != had_focus)
+ if (HAS_FOCUS (toplevel) != had_focus)
generate_focus_event (window, FALSE);
}
break;
? " (discarding substructure)"
: ""));
if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
- _gdk_x11_screen_size_changed (screen, xevent);
+ {
+ window_impl->width = xevent->xconfigure.width;
+ window_impl->height = xevent->xconfigure.height;
+
+ _gdk_x11_drawable_update_size (window_private->impl);
+ _gdk_x11_screen_size_changed (screen, xevent);
+ }
if (window &&
xevent->xconfigure.event == xevent->xconfigure.window &&
!GDK_WINDOW_DESTROYED (window) &&
(window_private->extension_events != 0))
_gdk_input_configure_event (&xevent->xconfigure, window);
+
+#ifdef HAVE_XSYNC
+ if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+ {
+ toplevel->current_counter_value = toplevel->pending_counter_value;
+ XSyncIntToValue (&toplevel->pending_counter_value, 0);
+ }
+#endif
- if (!window ||
+ if (!window ||
xevent->xconfigure.event != xevent->xconfigure.window ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
event->configure.width = xevent->xconfigure.width;
event->configure.height = xevent->xconfigure.height;
- if (!xevent->xconfigure.send_event &&
+ if (!xevent->xconfigure.send_event &&
+ !xevent->xconfigure.override_redirect &&
!GDK_WINDOW_DESTROYED (window))
{
gint tx = 0;
&tx, &ty,
&child_window))
{
- if (!gdk_error_trap_pop ())
- {
- event->configure.x = tx;
- event->configure.y = ty;
- }
+ event->configure.x = tx;
+ event->configure.y = ty;
}
- else
- gdk_error_trap_pop ();
+ gdk_error_trap_pop ();
}
else
{
}
window_private->x = event->configure.x;
window_private->y = event->configure.y;
- GDK_WINDOW_IMPL_X11 (window_private->impl)->width = xevent->xconfigure.width;
- GDK_WINDOW_IMPL_X11 (window_private->impl)->height = xevent->xconfigure.height;
+ window_impl->width = xevent->xconfigure.width;
+ window_impl->height = xevent->xconfigure.height;
+
+ _gdk_x11_drawable_update_size (window_private->impl);
+
if (window_private->resize_count >= 1)
{
window_private->resize_count -= 1;
return_val = FALSE;
break;
}
-
- if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE") ||
- xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
- {
- /* If window state changed, then synthesize those events. */
- gdk_check_wm_state_changed (window);
- }
+
+ /* We compare with the serial of the last time we mapped the
+ * window to avoid refetching properties that we set ourselves
+ */
+ if (toplevel &&
+ xevent->xproperty.serial >= toplevel->map_serial)
+ {
+ if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
+ gdk_check_wm_state_changed (window);
+
+ if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
+ gdk_check_wm_desktop_changed (window);
+ }
if (window_private->event_mask & GDK_PROPERTY_CHANGE_MASK)
{
while (tmp_list)
{
GdkClientFilter *filter = tmp_list->data;
+ tmp_list = tmp_list->next;
+
if (filter->type == message_type)
{
result = (*filter->function) (xevent, event, filter->data);
- break;
+ if (result != GDK_FILTER_CONTINUE)
+ break;
}
-
- tmp_list = tmp_list->next;
}
switch (result)
switch (xkb_event->any.xkb_type)
{
+ case XkbNewKeyboardNotify:
case XkbMapNotify:
_gdk_keymap_keys_changed (display);
break;
case XkbStateNotify:
- _gdk_keymap_state_changed (display);
+ _gdk_keymap_state_changed (display, xevent);
break;
}
}
else
+#endif
+#ifdef HAVE_XFIXES
+ if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
+ {
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
+
+ _gdk_x11_screen_process_owner_change (screen, xevent);
+
+ event->owner_change.type = GDK_OWNER_CHANGE;
+ event->owner_change.window = window;
+ event->owner_change.owner = selection_notify->owner;
+ event->owner_change.reason = selection_notify->subtype;
+ event->owner_change.selection =
+ gdk_x11_xatom_to_atom_for_display (display,
+ selection_notify->selection);
+ event->owner_change.time = selection_notify->timestamp;
+ event->owner_change.selection_time = selection_notify->selection_timestamp;
+
+ return_val = TRUE;
+ }
+ else
#endif
{
/* something else - (e.g., a Xinput event) */
{
XEvent *xevent = (XEvent *)xev;
GdkWindow *win = event->any.window;
- GdkDisplay *display = GDK_WINDOW_DISPLAY (win);
+ GdkDisplay *display;
+ Atom atom;
+
+ if (!win)
+ return GDK_FILTER_REMOVE;
- if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
+ display = GDK_WINDOW_DISPLAY (win);
+ atom = (Atom)xevent->xclient.data.l[0];
+
+ if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
{
/* The delete window request specifies a window
* to delete. We don't actually destroy the
event->any.type = GDK_DELETE;
+ gdk_x11_window_set_user_time (win, xevent->xclient.data.l[1]);
+
return GDK_FILTER_TRANSLATE;
}
- else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
{
- GdkWindow *win = event->any.window;
- Window focus_win = GDK_WINDOW_IMPL_X11(((GdkWindowObject *)win)->impl)->focus_window;
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+ GdkWindowObject *private = (GdkWindowObject *)win;
- /* There is no way of knowing reliably whether we are viewable so we need
- * to trap errors so we don't cause a BadMatch.
+ /* There is no way of knowing reliably whether we are viewable;
+ * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
*/
- gdk_error_trap_push ();
- XSetInputFocus (GDK_WINDOW_XDISPLAY (win),
- focus_win,
- RevertToParent,
- xevent->xclient.data.l[1]);
- XSync (GDK_WINDOW_XDISPLAY (win), False);
- gdk_error_trap_pop ();
+ if (toplevel && private->accept_focus)
+ _gdk_x11_set_input_focus_safe (display, toplevel->focus_window,
+ RevertToParent,
+ xevent->xclient.data.l[1]);
+
+ return GDK_FILTER_REMOVE;
}
- else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING"))
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
+ !_gdk_x11_display_is_root_window (display,
+ xevent->xclient.window))
{
- XEvent xev = *xevent;
+ XClientMessageEvent xclient = xevent->xclient;
- xev.xclient.window = GDK_WINDOW_XROOTWIN (win);
+ xclient.window = GDK_WINDOW_XROOTWIN (win);
XSendEvent (GDK_WINDOW_XDISPLAY (win),
- xev.xclient.window,
+ xclient.window,
False,
- SubstructureRedirectMask | SubstructureNotifyMask, &xev);
- }
+ SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
- return GDK_FILTER_REMOVE;
+ return GDK_FILTER_REMOVE;
+ }
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
+ GDK_DISPLAY_X11 (display)->use_sync)
+ {
+ GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+ if (toplevel)
+ {
+#ifdef HAVE_XSYNC
+ XSyncIntsToValue (&toplevel->pending_counter_value,
+ xevent->xclient.data.l[2],
+ xevent->xclient.data.l[3]);
+#endif
+ }
+ return GDK_FILTER_REMOVE;
+ }
+
+ return GDK_FILTER_CONTINUE;
}
void
}
/**
- * gdk_event_send_client_message_for_display :
- * @display : the #GdkDisplay for the window where the message is to be sent.
- * @event : the #GdkEvent to send, which should be a #GdkEventClient.
- * @winid : the window to send the X ClientMessage event to.
+ * gdk_event_send_client_message_for_display:
+ * @display: the #GdkDisplay for the window where the message is to be sent.
+ * @event: the #GdkEvent to send, which should be a #GdkEventClient.
+ * @winid: the window to send the client message to.
+ *
+ * On X11, sends an X ClientMessage event to a given window. On
+ * Windows, sends a message registered with the name
+ * GDK_WIN32_CLIENT_MESSAGE.
*
- * Sends an X ClientMessage event to a given window.
+ * This could be used for communicating between different
+ * applications, though the amount of data is limited to 20 bytes on
+ * X11, and to just four bytes on Windows.
*
- * This could be used for communicating between different applications,
- * though the amount of data is limited to 20 bytes.
+ * Returns: non-zero on success.
*
- * Returns : non-zero on success.
+ * Since: 2.2
*/
gboolean
gdk_event_send_client_message_for_display (GdkDisplay *display,
/* Sends a ClientMessage to all toplevel client windows */
-gboolean
+static gboolean
gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
XEvent *xev,
guint32 xid,
gdk_error_trap_push ();
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid,
- gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
+ gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"),
0, 0, False, AnyPropertyType,
&type, &format, &nitems, &after, &data) != Success)
goto out;
/**
* gdk_screen_broadcast_client_message:
- * @screen : the #GdkScreen where the event will be broadcasted.
- * @event : the #GdkEvent.
+ * @screen: the #GdkScreen where the event will be broadcasted.
+ * @event: the #GdkEvent.
*
- * Sends an X ClientMessage event to all toplevel windows on @screen.
+ * On X11, sends an X ClientMessage event to all toplevel windows on
+ * @screen.
*
* Toplevel windows are determined by checking for the WM_STATE property,
* as described in the Inter-Client Communication Conventions Manual (ICCCM).
* If no windows are found with the WM_STATE property set, the message is
* sent to all children of the root window.
+ *
+ * On Windows, broadcasts a message registered with the name
+ * GDK_WIN32_CLIENT_MESSAGE to all top-level windows. The amount of
+ * data is limited to one long, i.e. four bytes.
+ *
+ * Since: 2.2
*/
void
if (xevent->type == PropertyNotify &&
xevent->xproperty.window == xwindow &&
- xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display
- (gdk_display, "GDK_TIMESTAMP_PROP"))
+ xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
+ "GDK_TIMESTAMP_PROP"))
return True;
return False;
gint format;
gulong n_items;
gulong bytes_after;
+ guchar *data;
Window *xwindow;
/* This function is very slow on every call if you are not running a
screen_x11 = GDK_SCREEN_X11 (screen);
display = screen_x11->display;
+
+ g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client);
if (screen_x11->wmspec_check_window != None)
return; /* already have it */
+ data = NULL;
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window,
gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"),
0, G_MAXLONG, False, XA_WINDOW, &type, &format,
- &n_items, &bytes_after, (guchar **) & xwindow);
+ &n_items, &bytes_after, &data);
if (type != XA_WINDOW)
- return;
+ {
+ if (data)
+ XFree (data);
+ return;
+ }
+
+ xwindow = (Window *)data;
gdk_error_trap_push ();
/* Find out if this WM goes away, so we can reset everything. */
XSelectInput (screen_x11->xdisplay, *xwindow, StructureNotifyMask);
+ gdk_display_sync (display);
- screen_x11->wmspec_check_window = *xwindow;
- XFree (xwindow);
+ if (gdk_error_trap_pop () == Success)
+ {
+ screen_x11->wmspec_check_window = *xwindow;
+ screen_x11->need_refetch_net_supported = TRUE;
+ screen_x11->need_refetch_wm_name = TRUE;
+
+ /* Careful, reentrancy */
+ _gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
+ }
- screen_x11->need_refetch_net_supported = TRUE;
- screen_x11->need_refetch_wm_name = TRUE;
-
- /* Careful, reentrancy */
- _gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
+ XFree (xwindow);
}
+/**
+ * gdk_x11_screen_get_window_manager_name:
+ * @screen: a #GdkScreen
+ *
+ * Returns the name of the window manager for @screen.
+ *
+ * Return value: the name of the window manager screen @screen, or
+ * "unknown" if the window manager is unknown. The string is owned by GDK
+ * and should not be freed.
+ *
+ * Since: 2.2
+ **/
const char*
gdk_x11_screen_get_window_manager_name (GdkScreen *screen)
{
screen_x11 = GDK_SCREEN_X11 (screen);
+ if (!G_LIKELY (GDK_DISPLAY_X11 (screen_x11->display)->trusted_client))
+ return screen_x11->window_manager_name;
+
fetch_net_wm_check_window (screen);
if (screen_x11->need_refetch_wm_name)
gint format;
gulong n_items;
gulong bytes_after;
- guchar *name;
+ gchar *name;
name = NULL;
+
+ gdk_error_trap_push ();
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (screen_x11->display),
screen_x11->wmspec_check_window,
/**
* gdk_x11_screen_supports_net_wm_hint:
- * @screen : the relevant #GdkScreen.
+ * @screen: the relevant #GdkScreen.
* @property: a property atom.
*
* This function is specific to the X11 backend of GDK, and indicates
* whether the window manager supports a certain hint from the
* Extended Window Manager Hints Specification. You can find this
- * specification on http://www.freedesktop.org.
+ * specification on
+ * <ulink url="http://www.freedesktop.org">http://www.freedesktop.org</ulink>.
*
* When using this function, keep in mind that the window manager
* can change over time; so you shouldn't use this function in
* a window manager change.
*
* Return value: %TRUE if the window manager supports @property
+ *
+ * Since: 2.2
**/
gboolean
gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
screen_x11 = GDK_SCREEN_X11 (screen);
display = screen_x11->display;
+ if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
+ return FALSE;
+
supported_atoms = g_object_get_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms");
if (!supported_atoms)
{
return gdk_x11_screen_supports_net_wm_hint (gdk_screen_get_default (), property);
}
-static struct
-{
- const char *xsettings_name;
- const char *gdk_name;
-} settings_map[] = {
- { "Net/DoubleClickTime", "gtk-double-click-time" },
- { "Net/DndDragThreshold", "gtk-dnd-drag-threshold" },
- { "Gtk/CanChangeAccels", "gtk-can-change-accels" },
- { "Gtk/ColorPalette", "gtk-color-palette" },
- { "Gtk/FontName", "gtk-font-name" },
- { "Gtk/IconSizes", "gtk-icon-sizes" },
- { "Gtk/KeyThemeName", "gtk-key-theme-name" },
- { "Gtk/ToolbarStyle", "gtk-toolbar-style" },
- { "Gtk/ToolbarIconSize", "gtk-toolbar-icon-size" },
- { "Gtk/IMPreeditStyle", "gtk-im-preedit-style" },
- { "Gtk/IMStatusStyle", "gtk-im-status-style" },
- { "Net/CursorBlink", "gtk-cursor-blink" },
- { "Net/CursorBlinkTime", "gtk-cursor-blink-time" },
- { "Net/ThemeName", "gtk-theme-name" }
-};
static void
gdk_xsettings_notify_cb (const char *name,
new_event.setting.send_event = FALSE;
new_event.setting.name = NULL;
- for (i = 0; i < G_N_ELEMENTS (settings_map) ; i++)
- if (strcmp (settings_map[i].xsettings_name, name) == 0)
+ for (i = 0; i < GDK_SETTINGS_N_ELEMENTS() ; i++)
+ if (strcmp (GDK_SETTINGS_X_NAME (i), name) == 0)
{
- new_event.setting.name = (char *)settings_map[i].gdk_name;
+ new_event.setting.name = (char*) GDK_SETTINGS_GDK_NAME (i);
break;
}
-
if (!new_event.setting.name)
return;
{
if (!g_value_type_transformable (src_type, dest_type))
{
- g_warning ("Cannot tranform xsetting %s of type %s to type %s\n",
+ g_warning ("Cannot transform xsetting %s of type %s to type %s\n",
xsettings_name,
g_type_name (src_type),
g_type_name (dest_type));
* FIXME needs a list of valid settings here, or a link to
* more information.
*
- * Returns : %TRUE if the setting existed and a value was stored
+ * Returns: %TRUE if the setting existed and a value was stored
* in @value, %FALSE otherwise.
+ *
+ * Since: 2.2
**/
gboolean
gdk_screen_get_setting (GdkScreen *screen,
const char *xsettings_name = NULL;
XSettingsResult result;
- XSettingsSetting *setting;
+ XSettingsSetting *setting = NULL;
GdkScreenX11 *screen_x11;
gboolean success = FALSE;
gint i;
screen_x11 = GDK_SCREEN_X11 (screen);
- for (i = 0; i < G_N_ELEMENTS (settings_map) ; i++)
- if (strcmp (settings_map[i].gdk_name, name) == 0)
+ for (i = 0; i < GDK_SETTINGS_N_ELEMENTS(); i++)
+ if (strcmp (GDK_SETTINGS_GDK_NAME (i), name) == 0)
{
- xsettings_name = settings_map[i].xsettings_name;
+ xsettings_name = GDK_SETTINGS_X_NAME (i);
break;
}
if (!xsettings_name)
- return FALSE;
+ goto out;
result = xsettings_client_get_setting (screen_x11->xsettings_client,
xsettings_name, &setting);
if (result != XSETTINGS_SUCCESS)
- return FALSE;
+ goto out;
switch (setting->type)
{
g_value_unset (&tmp_val);
- xsettings_setting_free (setting);
+ out:
+ if (setting)
+ xsettings_setting_free (setting);
- return success;
+ if (success)
+ return TRUE;
+ else
+ return _gdk_x11_get_xft_setting (screen, name, value);
}
static GdkFilterReturn
{
if (!gdkwin)
gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
- else
- g_object_ref (gdkwin);
gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
}
else
{
- g_assert (gdkwin);
- gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
- g_object_unref (gdkwin);
+ if (gdkwin)
+ gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
}
}
+
+#define __GDK_EVENTS_X11_C__
+#include "gdkaliasdef.c"