1
/* GDK - The GIMP Drawing Kit
2
* Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3
* Josh MacDonald, Ryan Lortie
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
22
* Modified by the GTK+ Team and others 1997-2007. See the AUTHORS
23
* file for a list of people on the GTK+ Team. See the ChangeLog
24
* files for a list of changes. These files are distributed with
25
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31
#include "gdkprivate-x11.h"
32
#include "gdkinternals.h"
34
#include "gdkscreen-x11.h"
35
#include "gdkdisplay-x11.h"
38
#include "gdkkeysyms.h"
40
#include "xsettings-client.h"
44
#include "gdkinputprivate.h"
45
#include "gdksettings.c"
50
#include <X11/XKBlib.h>
54
#include <X11/extensions/sync.h>
58
#include <X11/extensions/Xfixes.h>
62
#include <X11/extensions/Xrandr.h>
65
#include <X11/Xatom.h>
67
typedef struct _GdkIOClosure GdkIOClosure;
68
typedef struct _GdkDisplaySource GdkDisplaySource;
69
typedef struct _GdkEventTypeX11 GdkEventTypeX11;
73
GdkInputFunction function;
74
GdkInputCondition condition;
75
GDestroyNotify notify;
79
struct _GdkDisplaySource
84
GPollFD event_poll_fd;
87
struct _GdkEventTypeX11
94
* Private function declarations
97
static gint gdk_event_apply_filters (XEvent *xevent,
100
static gboolean gdk_event_translate (GdkDisplay *display,
103
gboolean return_exposes);
105
static gboolean gdk_event_prepare (GSource *source,
107
static gboolean gdk_event_check (GSource *source);
108
static gboolean gdk_event_dispatch (GSource *source,
109
GSourceFunc callback,
112
static GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
116
static GSource *gdk_display_source_new (GdkDisplay *display);
117
static gboolean gdk_check_xpending (GdkDisplay *display);
119
static Bool gdk_xsettings_watch_cb (Window window,
123
static void gdk_xsettings_notify_cb (const char *name,
124
XSettingsAction action,
125
XSettingsSetting *setting,
128
/* Private variable declarations
131
static GList *display_sources;
133
static GSourceFuncs event_funcs = {
141
gdk_display_source_new (GdkDisplay *display)
143
GSource *source = g_source_new (&event_funcs, sizeof (GdkDisplaySource));
144
GdkDisplaySource *display_source = (GdkDisplaySource *)source;
147
name = g_strdup_printf ("GDK X11 Event source (%s)",
148
gdk_display_get_name (display));
149
g_source_set_name (source, name);
151
display_source->display = display;
157
gdk_check_xpending (GdkDisplay *display)
159
return XPending (GDK_DISPLAY_XDISPLAY (display));
162
/*********************************************
163
* Functions for maintaining the event queue *
164
*********************************************/
167
refcounted_grab_server (Display *xdisplay)
169
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
171
gdk_x11_display_grab (display);
175
refcounted_ungrab_server (Display *xdisplay)
177
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
179
gdk_x11_display_ungrab (display);
183
_gdk_x11_events_init_screen (GdkScreen *screen)
185
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
187
/* Keep a flag to avoid extra notifies that we don't need
189
screen_x11->xsettings_in_init = TRUE;
190
screen_x11->xsettings_client = xsettings_client_new_with_grab_funcs (screen_x11->xdisplay,
191
screen_x11->screen_num,
192
gdk_xsettings_notify_cb,
193
gdk_xsettings_watch_cb,
195
refcounted_grab_server,
196
refcounted_ungrab_server);
197
screen_x11->xsettings_in_init = FALSE;
201
_gdk_x11_events_uninit_screen (GdkScreen *screen)
203
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
205
if (screen_x11->xsettings_client)
207
xsettings_client_destroy (screen_x11->xsettings_client);
208
screen_x11->xsettings_client = NULL;
213
_gdk_events_init (GdkDisplay *display)
216
GdkDisplaySource *display_source;
217
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
219
int connection_number = ConnectionNumber (display_x11->xdisplay);
220
GDK_NOTE (MISC, g_message ("connection number: %d", connection_number));
223
source = display_x11->event_source = gdk_display_source_new (display);
224
display_source = (GdkDisplaySource*) source;
225
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
227
display_source->event_poll_fd.fd = connection_number;
228
display_source->event_poll_fd.events = G_IO_IN;
230
g_source_add_poll (source, &display_source->event_poll_fd);
231
g_source_set_can_recurse (source, TRUE);
232
g_source_attach (source, NULL);
234
display_sources = g_list_prepend (display_sources,display_source);
236
gdk_display_add_client_message_filter (display,
237
gdk_atom_intern_static_string ("WM_PROTOCOLS"),
238
gdk_wm_protocols_filter,
243
_gdk_events_uninit (GdkDisplay *display)
245
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
247
if (display_x11->event_source)
249
display_sources = g_list_remove (display_sources,
250
display_x11->event_source);
251
g_source_destroy (display_x11->event_source);
252
g_source_unref (display_x11->event_source);
253
display_x11->event_source = NULL;
258
* gdk_events_pending:
260
* Checks if any events are ready to be processed for any display.
262
* Return value: %TRUE if any events are pending.
265
gdk_events_pending (void)
269
for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
271
GdkDisplaySource *tmp_source = tmp_list->data;
272
GdkDisplay *display = tmp_source->display;
274
if (_gdk_event_queue_find_first (display))
278
for (tmp_list = display_sources; tmp_list; tmp_list = tmp_list->next)
280
GdkDisplaySource *tmp_source = tmp_list->data;
281
GdkDisplay *display = tmp_source->display;
283
if (gdk_check_xpending (display))
291
graphics_expose_predicate (Display *display,
295
if (xevent->xany.window == GDK_DRAWABLE_XID ((GdkDrawable *)arg) &&
296
(xevent->xany.type == GraphicsExpose ||
297
xevent->xany.type == NoExpose))
304
* gdk_event_get_graphics_expose:
305
* @window: the #GdkWindow to wait for the events for.
307
* Waits for a GraphicsExpose or NoExpose event from the X server.
308
* This is used in the #GtkText and #GtkCList widgets in GTK+ to make sure any
309
* GraphicsExpose events are handled before the widget is scrolled.
311
* Return value: a #GdkEventExpose if a GraphicsExpose was received, or %NULL if a
312
* NoExpose event was received.
317
gdk_event_get_graphics_expose (GdkWindow *window)
322
g_return_val_if_fail (window != NULL, NULL);
324
XIfEvent (GDK_WINDOW_XDISPLAY (window), &xevent,
325
graphics_expose_predicate, (XPointer) window);
327
if (xevent.xany.type == GraphicsExpose)
329
event = gdk_event_new (GDK_NOTHING);
331
if (gdk_event_translate (GDK_WINDOW_DISPLAY (window), event,
335
gdk_event_free (event);
342
gdk_event_apply_filters (XEvent *xevent,
347
GdkFilterReturn result;
353
GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
356
if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0)
358
tmp_list = tmp_list->next;
363
result = filter->function (xevent, event, filter->data);
365
/* get the next node after running the function since the
366
function may add or remove a next node */
368
tmp_list = tmp_list->next;
371
if (filter->ref_count == 0)
373
*filters = g_list_remove_link (*filters, node);
374
g_list_free_1 (node);
378
if (result != GDK_FILTER_CONTINUE)
382
return GDK_FILTER_CONTINUE;
386
* gdk_display_add_client_message_filter:
387
* @display: a #GdkDisplay for which this message filter applies
388
* @message_type: the type of ClientMessage events to receive.
389
* This will be checked against the @message_type field
390
* of the XClientMessage event struct.
391
* @func: the function to call to process the event.
392
* @data: user data to pass to @func.
394
* Adds a filter to be called when X ClientMessage events are received.
395
* See gdk_window_add_filter() if you are interested in filtering other
401
gdk_display_add_client_message_filter (GdkDisplay *display,
402
GdkAtom message_type,
406
GdkClientFilter *filter;
407
g_return_if_fail (GDK_IS_DISPLAY (display));
408
filter = g_new (GdkClientFilter, 1);
410
filter->type = message_type;
411
filter->function = func;
414
GDK_DISPLAY_X11(display)->client_filters =
415
g_list_append (GDK_DISPLAY_X11 (display)->client_filters,
420
* gdk_add_client_message_filter:
421
* @message_type: the type of ClientMessage events to receive. This will be
422
* checked against the <structfield>message_type</structfield> field of the
423
* XClientMessage event struct.
424
* @func: the function to call to process the event.
425
* @data: user data to pass to @func.
427
* Adds a filter to the default display to be called when X ClientMessage events
428
* are received. See gdk_display_add_client_message_filter().
431
gdk_add_client_message_filter (GdkAtom message_type,
435
gdk_display_add_client_message_filter (gdk_display_get_default (),
436
message_type, func, data);
440
do_net_wm_state_changes (GdkWindow *window)
442
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
443
GdkWindowState old_state;
445
if (GDK_WINDOW_DESTROYED (window) ||
446
gdk_window_get_window_type (window) != GDK_WINDOW_TOPLEVEL)
449
old_state = gdk_window_get_state (window);
451
/* For found_sticky to remain TRUE, we have to also be on desktop
454
if (old_state & GDK_WINDOW_STATE_STICKY)
456
if (!(toplevel->have_sticky && toplevel->on_all_desktops))
457
gdk_synthesize_window_state (window,
458
GDK_WINDOW_STATE_STICKY,
463
if (toplevel->have_sticky || toplevel->on_all_desktops)
464
gdk_synthesize_window_state (window,
466
GDK_WINDOW_STATE_STICKY);
469
if (old_state & GDK_WINDOW_STATE_FULLSCREEN)
471
if (!toplevel->have_fullscreen)
472
gdk_synthesize_window_state (window,
473
GDK_WINDOW_STATE_FULLSCREEN,
478
if (toplevel->have_fullscreen)
479
gdk_synthesize_window_state (window,
481
GDK_WINDOW_STATE_FULLSCREEN);
484
/* Our "maximized" means both vertical and horizontal; if only one,
485
* we don't expose that via GDK
487
if (old_state & GDK_WINDOW_STATE_MAXIMIZED)
489
if (!(toplevel->have_maxvert && toplevel->have_maxhorz))
490
gdk_synthesize_window_state (window,
491
GDK_WINDOW_STATE_MAXIMIZED,
496
if (toplevel->have_maxvert && toplevel->have_maxhorz)
497
gdk_synthesize_window_state (window,
499
GDK_WINDOW_STATE_MAXIMIZED);
502
if (old_state & GDK_WINDOW_STATE_ICONIFIED)
504
if (!toplevel->have_hidden)
505
gdk_synthesize_window_state (window,
506
GDK_WINDOW_STATE_ICONIFIED,
511
if (toplevel->have_hidden)
512
gdk_synthesize_window_state (window,
514
GDK_WINDOW_STATE_ICONIFIED);
519
gdk_check_wm_desktop_changed (GdkWindow *window)
521
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
522
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
532
gdk_error_trap_push ();
533
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
534
GDK_WINDOW_XID (window),
535
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
536
0, G_MAXLONG, False, XA_CARDINAL, &type,
538
&bytes_after, &data);
539
gdk_error_trap_pop ();
543
desktop = (gulong *)data;
544
toplevel->on_all_desktops = (*desktop == 0xFFFFFFFF);
548
toplevel->on_all_desktops = FALSE;
550
do_net_wm_state_changes (window);
554
gdk_check_wm_state_changed (GdkWindow *window)
556
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
557
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
567
gboolean had_sticky = toplevel->have_sticky;
569
toplevel->have_sticky = FALSE;
570
toplevel->have_maxvert = FALSE;
571
toplevel->have_maxhorz = FALSE;
572
toplevel->have_fullscreen = FALSE;
573
toplevel->have_hidden = FALSE;
576
gdk_error_trap_push ();
577
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
578
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
579
0, G_MAXLONG, False, XA_ATOM, &type, &format, &nitems,
580
&bytes_after, &data);
581
gdk_error_trap_pop ();
585
Atom sticky_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_STICKY");
586
Atom maxvert_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_VERT");
587
Atom maxhorz_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_MAXIMIZED_HORZ");
588
Atom fullscreen_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_FULLSCREEN");
589
Atom hidden_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE_HIDDEN");
591
atoms = (Atom *)data;
596
if (atoms[i] == sticky_atom)
597
toplevel->have_sticky = TRUE;
598
else if (atoms[i] == maxvert_atom)
599
toplevel->have_maxvert = TRUE;
600
else if (atoms[i] == maxhorz_atom)
601
toplevel->have_maxhorz = TRUE;
602
else if (atoms[i] == fullscreen_atom)
603
toplevel->have_fullscreen = TRUE;
604
else if (atoms[i] == hidden_atom)
605
toplevel->have_hidden = TRUE;
613
/* When have_sticky is turned on, we have to check the DESKTOP property
616
if (toplevel->have_sticky && !had_sticky)
617
gdk_check_wm_desktop_changed (window);
619
do_net_wm_state_changes (window);
622
#define HAS_FOCUS(toplevel) \
623
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
626
generate_focus_event (GdkWindow *window,
631
event.type = GDK_FOCUS_CHANGE;
632
event.focus_change.window = window;
633
event.focus_change.send_event = FALSE;
634
event.focus_change.in = in;
636
gdk_event_put (&event);
640
set_screen_from_root (GdkDisplay *display,
646
screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
650
gdk_event_set_screen (event, screen);
659
translate_key_event (GdkDisplay *display,
663
GdkKeymap *keymap = gdk_keymap_get_for_display (display);
666
GdkModifierType consumed, state;
668
event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
669
event->key.time = xevent->xkey.time;
671
event->key.state = (GdkModifierType) xevent->xkey.state;
672
event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
673
event->key.hardware_keycode = xevent->xkey.keycode;
675
event->key.keyval = GDK_VoidSymbol;
677
gdk_keymap_translate_keyboard_state (keymap,
678
event->key.hardware_keycode,
682
NULL, NULL, &consumed);
683
state = event->key.state & ~consumed;
684
_gdk_keymap_add_virtual_modifiers_compat (keymap, &state);
685
event->key.state |= state;
687
event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
689
/* Fill in event->string crudely, since various programs
692
event->key.string = NULL;
694
if (event->key.keyval != GDK_VoidSymbol)
695
c = gdk_keyval_to_unicode (event->key.keyval);
702
/* Apply the control key - Taken from Xlib
704
if (event->key.state & GDK_CONTROL_MASK)
706
if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
709
event->key.string = g_memdup ("\0\0", 2);
710
event->key.length = 1;
714
else if (c >= '3' && c <= '7') c -= ('3' - '\033');
715
else if (c == '8') c = '\177';
716
else if (c == '/') c = '_' & 0x1F;
719
len = g_unichar_to_utf8 (c, buf);
722
event->key.string = g_locale_from_utf8 (buf, len,
723
NULL, &bytes_written,
725
if (event->key.string)
726
event->key.length = bytes_written;
728
else if (event->key.keyval == GDK_Escape)
730
event->key.length = 1;
731
event->key.string = g_strdup ("\033");
733
else if (event->key.keyval == GDK_Return ||
734
event->key.keyval == GDK_KP_Enter)
736
event->key.length = 1;
737
event->key.string = g_strdup ("\r");
740
if (!event->key.string)
742
event->key.length = 0;
743
event->key.string = g_strdup ("");
747
#ifdef G_ENABLE_DEBUG
748
if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
750
g_message ("%s:\t\twindow: %ld key: %12s %d",
751
event->type == GDK_KEY_PRESS ? "key press " : "key release",
753
event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
756
if (event->key.length > 0)
757
g_message ("\t\tlength: %4d string: \"%s\"",
758
event->key.length, buf);
760
#endif /* G_ENABLE_DEBUG */
765
* gdk_x11_register_standard_event_type:
766
* @display: a #GdkDisplay
767
* @event_base: first event type code to register
768
* @n_events: number of event type codes to register
770
* Registers interest in receiving extension events with type codes
771
* between @event_base and <literal>event_base + n_events - 1</literal>.
772
* The registered events must have the window field in the same place
773
* as core X events (this is not the case for e.g. XKB extension events).
775
* If an event type is registered, events of this type will go through
776
* global and window-specific filters (see gdk_window_add_filter()).
777
* Unregistered events will only go through global filters.
778
* GDK may register the events of some X extensions on its own.
780
* This function should only be needed in unusual circumstances, e.g.
781
* when filtering XInput extension events on the root window.
786
gdk_x11_register_standard_event_type (GdkDisplay *display,
790
GdkEventTypeX11 *event_type;
791
GdkDisplayX11 *display_x11;
793
display_x11 = GDK_DISPLAY_X11 (display);
794
event_type = g_new (GdkEventTypeX11, 1);
796
event_type->base = event_base;
797
event_type->n_events = n_events;
799
display_x11->event_types = g_slist_prepend (display_x11->event_types, event_type);
802
/* Return the window this has to do with, if any, rather
803
* than the frame or root window that was selecting
807
get_real_window (GdkDisplay *display,
809
Window *event_window,
810
Window *filter_window)
812
/* Core events all have an event->xany.window field, but that's
813
* not true for extension events
815
if (event->type >= KeyPress &&
816
event->type <= MappingNotify)
818
*filter_window = event->xany.window;
822
*event_window = event->xcreatewindow.window;
825
*event_window = event->xdestroywindow.window;
828
*event_window = event->xunmap.window;
831
*event_window = event->xmap.window;
834
*event_window = event->xmaprequest.window;
837
*event_window = event->xreparent.window;
839
case ConfigureNotify:
840
*event_window = event->xconfigure.window;
842
case ConfigureRequest:
843
*event_window = event->xconfigurerequest.window;
846
*event_window = event->xgravity.window;
848
case CirculateNotify:
849
*event_window = event->xcirculate.window;
851
case CirculateRequest:
852
*event_window = event->xcirculaterequest.window;
855
*event_window = event->xany.window;
860
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
863
for (tmp_list = display_x11->event_types;
865
tmp_list = tmp_list->next)
867
GdkEventTypeX11 *event_type = tmp_list->data;
869
if (event->type >= event_type->base &&
870
event->type < event_type->base + event_type->n_events)
872
*event_window = event->xany.window;
873
*filter_window = event->xany.window;
878
*event_window = None;
879
*filter_window = None;
883
#ifdef G_ENABLE_DEBUG
884
static const char notify_modes[][19] = {
891
static const char notify_details[][23] = {
896
"NotifyNonlinearVirtual",
904
set_user_time (GdkWindow *window,
907
g_return_if_fail (event != NULL);
909
window = gdk_window_get_toplevel (event->client.window);
910
g_return_if_fail (GDK_IS_WINDOW (window));
912
/* If an event doesn't have a valid timestamp, we shouldn't use it
913
* to update the latest user interaction time.
915
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
916
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
917
gdk_event_get_time (event));
921
is_parent_of (GdkWindow *parent,
932
w = gdk_window_get_parent (w);
939
gdk_event_translate (GdkDisplay *display,
942
gboolean return_exposes)
946
GdkWindowObject *window_private;
947
GdkWindow *filter_window;
948
GdkWindowImplX11 *window_impl = NULL;
950
GdkScreen *screen = NULL;
951
GdkScreenX11 *screen_x11 = NULL;
952
GdkToplevelX11 *toplevel = NULL;
953
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
954
Window xwindow, filter_xwindow;
958
/* init these, since the done: block uses them */
960
window_private = NULL;
961
event->any.window = NULL;
963
if (_gdk_default_filters)
965
/* Apply global filters */
966
GdkFilterReturn result;
967
result = gdk_event_apply_filters (xevent, event,
968
&_gdk_default_filters);
970
if (result != GDK_FILTER_CONTINUE)
972
return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
977
/* Find the GdkWindow that this event relates to.
978
* Basically this means substructure events
979
* are reported same as structure events
981
get_real_window (display, xevent, &xwindow, &filter_xwindow);
983
window = gdk_window_lookup_for_display (display, xwindow);
984
/* We may receive events such as NoExpose/GraphicsExpose
985
* and ShmCompletion for pixmaps
987
if (window && !GDK_IS_WINDOW (window))
989
window_private = (GdkWindowObject *) window;
991
/* We always run the filters for the window where the event
992
* is delivered, not the window that it relates to
994
if (filter_xwindow == xwindow)
995
filter_window = window;
998
filter_window = gdk_window_lookup_for_display (display, filter_xwindow);
999
if (filter_window && !GDK_IS_WINDOW (filter_window))
1000
filter_window = NULL;
1005
screen = GDK_WINDOW_SCREEN (window);
1006
screen_x11 = GDK_SCREEN_X11 (screen);
1007
toplevel = _gdk_x11_window_get_toplevel (window);
1012
/* Apply keyboard grabs to non-native windows */
1013
if (/* Is key event */
1014
(xevent->type == KeyPress || xevent->type == KeyRelease) &&
1015
/* And we have a grab */
1016
display->keyboard_grab.window != NULL &&
1018
/* The window is not a descendant of the grabbed window */
1019
!is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
1020
/* Or owner event is false */
1021
!display->keyboard_grab.owner_events
1025
/* Report key event against grab window */
1026
window = display->keyboard_grab.window;;
1027
window_private = (GdkWindowObject *) window;
1030
window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
1032
/* Move key events on focus window to the real toplevel, and
1033
* filter out all other events on focus window
1035
if (toplevel && xwindow == toplevel->focus_window)
1037
switch (xevent->type)
1041
xwindow = GDK_WINDOW_XID (window);
1042
xevent->xany.window = xwindow;
1049
g_object_ref (window);
1052
event->any.window = window;
1053
event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
1055
if (window_private && GDK_WINDOW_DESTROYED (window))
1057
if (xevent->type != DestroyNotify)
1063
else if (filter_window)
1065
/* Apply per-window filters */
1066
GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
1067
GdkFilterReturn result;
1069
if (filter_private->filters)
1071
g_object_ref (filter_window);
1073
result = gdk_event_apply_filters (xevent, event,
1074
&filter_private->filters);
1076
g_object_unref (filter_window);
1078
if (result != GDK_FILTER_CONTINUE)
1080
return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1086
if (xevent->type == DestroyNotify)
1090
n = gdk_display_get_n_screens (display);
1091
for (i = 0; i < n; i++)
1093
screen = gdk_display_get_screen (display, i);
1094
screen_x11 = GDK_SCREEN_X11 (screen);
1096
if (screen_x11->wmspec_check_window == xwindow)
1098
screen_x11->wmspec_check_window = None;
1099
screen_x11->last_wmspec_check_time = 0;
1100
g_free (screen_x11->window_manager_name);
1101
screen_x11->window_manager_name = g_strdup ("unknown");
1103
/* careful, reentrancy */
1104
_gdk_x11_screen_window_manager_changed (screen);
1113
(xevent->xany.type == MotionNotify ||
1114
xevent->xany.type == ButtonRelease))
1116
if (_gdk_moveresize_handle_event (xevent))
1123
/* We do a "manual" conversion of the XEvent to a
1124
* GdkEvent. The structures are mostly the same so
1125
* the conversion is fairly straightforward. We also
1126
* optionally print debugging info regarding events
1132
switch (xevent->type)
1135
if (window_private == NULL)
1140
translate_key_event (display, event, xevent);
1141
set_user_time (window, event);
1145
if (window_private == NULL)
1151
/* Emulate detectable auto-repeat by checking to see
1152
* if the next event is a key press with the same
1153
* keycode and timestamp, and if so, ignoring the event.
1156
if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
1160
XPeekEvent (xevent->xkey.display, &next_event);
1162
if (next_event.type == KeyPress &&
1163
next_event.xkey.keycode == xevent->xkey.keycode &&
1164
next_event.xkey.time == xevent->xkey.time)
1171
translate_key_event (display, event, xevent);
1176
g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d",
1177
xevent->xbutton.window,
1178
xevent->xbutton.x, xevent->xbutton.y,
1179
xevent->xbutton.button));
1181
if (window_private == NULL)
1187
/* If we get a ButtonPress event where the button is 4 or 5,
1188
it's a Scroll event */
1189
switch (xevent->xbutton.button)
1195
event->scroll.type = GDK_SCROLL;
1197
if (xevent->xbutton.button == 4)
1198
event->scroll.direction = GDK_SCROLL_UP;
1199
else if (xevent->xbutton.button == 5)
1200
event->scroll.direction = GDK_SCROLL_DOWN;
1201
else if (xevent->xbutton.button == 6)
1202
event->scroll.direction = GDK_SCROLL_LEFT;
1204
event->scroll.direction = GDK_SCROLL_RIGHT;
1206
event->scroll.window = window;
1207
event->scroll.time = xevent->xbutton.time;
1208
event->scroll.x = xevent->xbutton.x;
1209
event->scroll.y = xevent->xbutton.y;
1210
event->scroll.x_root = (gfloat)xevent->xbutton.x_root;
1211
event->scroll.y_root = (gfloat)xevent->xbutton.y_root;
1212
event->scroll.state = (GdkModifierType) xevent->xbutton.state;
1213
event->scroll.device = display->core_pointer;
1215
if (!set_screen_from_root (display, event, xevent->xbutton.root))
1224
event->button.type = GDK_BUTTON_PRESS;
1225
event->button.window = window;
1226
event->button.time = xevent->xbutton.time;
1227
event->button.x = xevent->xbutton.x;
1228
event->button.y = xevent->xbutton.y;
1229
event->button.x_root = (gfloat)xevent->xbutton.x_root;
1230
event->button.y_root = (gfloat)xevent->xbutton.y_root;
1231
event->button.axes = NULL;
1232
event->button.state = (GdkModifierType) xevent->xbutton.state;
1233
event->button.button = xevent->xbutton.button;
1234
event->button.device = display->core_pointer;
1236
if (!set_screen_from_root (display, event, xevent->xbutton.root))
1244
set_user_time (window, event);
1250
g_message ("button release:\twindow: %ld x,y: %d %d button: %d",
1251
xevent->xbutton.window,
1252
xevent->xbutton.x, xevent->xbutton.y,
1253
xevent->xbutton.button));
1255
if (window_private == NULL)
1261
/* We treat button presses as scroll wheel events, so ignore the release */
1262
if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
1263
xevent->xbutton.button == 6 || xevent->xbutton.button ==7)
1269
event->button.type = GDK_BUTTON_RELEASE;
1270
event->button.window = window;
1271
event->button.time = xevent->xbutton.time;
1272
event->button.x = xevent->xbutton.x;
1273
event->button.y = xevent->xbutton.y;
1274
event->button.x_root = (gfloat)xevent->xbutton.x_root;
1275
event->button.y_root = (gfloat)xevent->xbutton.y_root;
1276
event->button.axes = NULL;
1277
event->button.state = (GdkModifierType) xevent->xbutton.state;
1278
event->button.button = xevent->xbutton.button;
1279
event->button.device = display->core_pointer;
1281
if (!set_screen_from_root (display, event, xevent->xbutton.root))
1288
g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s",
1289
xevent->xmotion.window,
1290
xevent->xmotion.x, xevent->xmotion.y,
1291
(xevent->xmotion.is_hint) ? "true" : "false"));
1293
if (window_private == NULL)
1299
event->motion.type = GDK_MOTION_NOTIFY;
1300
event->motion.window = window;
1301
event->motion.time = xevent->xmotion.time;
1302
event->motion.x = xevent->xmotion.x;
1303
event->motion.y = xevent->xmotion.y;
1304
event->motion.x_root = (gfloat)xevent->xmotion.x_root;
1305
event->motion.y_root = (gfloat)xevent->xmotion.y_root;
1306
event->motion.axes = NULL;
1307
event->motion.state = (GdkModifierType) xevent->xmotion.state;
1308
event->motion.is_hint = xevent->xmotion.is_hint;
1309
event->motion.device = display->core_pointer;
1311
if (!set_screen_from_root (display, event, xevent->xbutton.root))
1321
g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld mode: %d",
1322
xevent->xcrossing.window,
1323
xevent->xcrossing.detail,
1324
xevent->xcrossing.subwindow,
1325
xevent->xcrossing.mode));
1327
if (window_private == NULL)
1333
if (!set_screen_from_root (display, event, xevent->xbutton.root))
1339
/* Handle focusing (in the case where no window manager is running */
1340
if (toplevel && xevent->xcrossing.detail != NotifyInferior)
1342
toplevel->has_pointer = TRUE;
1344
if (xevent->xcrossing.focus && !toplevel->has_focus_window)
1346
gboolean had_focus = HAS_FOCUS (toplevel);
1348
toplevel->has_pointer_focus = TRUE;
1350
if (HAS_FOCUS (toplevel) != had_focus)
1351
generate_focus_event (window, TRUE);
1355
event->crossing.type = GDK_ENTER_NOTIFY;
1356
event->crossing.window = window;
1358
/* If the subwindow field of the XEvent is non-NULL, then
1359
* lookup the corresponding GdkWindow.
1361
if (xevent->xcrossing.subwindow != None)
1362
event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
1364
event->crossing.subwindow = NULL;
1366
event->crossing.time = xevent->xcrossing.time;
1367
event->crossing.x = xevent->xcrossing.x;
1368
event->crossing.y = xevent->xcrossing.y;
1369
event->crossing.x_root = xevent->xcrossing.x_root;
1370
event->crossing.y_root = xevent->xcrossing.y_root;
1372
/* Translate the crossing mode into Gdk terms.
1374
switch (xevent->xcrossing.mode)
1377
event->crossing.mode = GDK_CROSSING_NORMAL;
1380
event->crossing.mode = GDK_CROSSING_GRAB;
1383
event->crossing.mode = GDK_CROSSING_UNGRAB;
1387
/* Translate the crossing detail into Gdk terms.
1389
switch (xevent->xcrossing.detail)
1391
case NotifyInferior:
1392
event->crossing.detail = GDK_NOTIFY_INFERIOR;
1394
case NotifyAncestor:
1395
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1398
event->crossing.detail = GDK_NOTIFY_VIRTUAL;
1400
case NotifyNonlinear:
1401
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1403
case NotifyNonlinearVirtual:
1404
event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
1407
event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1411
event->crossing.focus = xevent->xcrossing.focus;
1412
event->crossing.state = xevent->xcrossing.state;
1418
g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld mode: %d",
1419
xevent->xcrossing.window,
1420
xevent->xcrossing.detail,
1421
xevent->xcrossing.subwindow,
1422
xevent->xcrossing.mode));
1424
if (window_private == NULL)
1430
if (!set_screen_from_root (display, event, xevent->xbutton.root))
1436
/* Handle focusing (in the case where no window manager is running */
1437
if (toplevel && xevent->xcrossing.detail != NotifyInferior)
1439
toplevel->has_pointer = FALSE;
1441
if (xevent->xcrossing.focus && !toplevel->has_focus_window)
1443
gboolean had_focus = HAS_FOCUS (toplevel);
1445
toplevel->has_pointer_focus = FALSE;
1447
if (HAS_FOCUS (toplevel) != had_focus)
1448
generate_focus_event (window, FALSE);
1452
event->crossing.type = GDK_LEAVE_NOTIFY;
1453
event->crossing.window = window;
1455
/* If the subwindow field of the XEvent is non-NULL, then
1456
* lookup the corresponding GdkWindow.
1458
if (xevent->xcrossing.subwindow != None)
1459
event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
1461
event->crossing.subwindow = NULL;
1463
event->crossing.time = xevent->xcrossing.time;
1464
event->crossing.x = xevent->xcrossing.x;
1465
event->crossing.y = xevent->xcrossing.y;
1466
event->crossing.x_root = xevent->xcrossing.x_root;
1467
event->crossing.y_root = xevent->xcrossing.y_root;
1469
/* Translate the crossing mode into Gdk terms.
1471
switch (xevent->xcrossing.mode)
1474
event->crossing.mode = GDK_CROSSING_NORMAL;
1477
event->crossing.mode = GDK_CROSSING_GRAB;
1480
event->crossing.mode = GDK_CROSSING_UNGRAB;
1484
/* Translate the crossing detail into Gdk terms.
1486
switch (xevent->xcrossing.detail)
1488
case NotifyInferior:
1489
event->crossing.detail = GDK_NOTIFY_INFERIOR;
1491
case NotifyAncestor:
1492
event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1495
event->crossing.detail = GDK_NOTIFY_VIRTUAL;
1497
case NotifyNonlinear:
1498
event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1500
case NotifyNonlinearVirtual:
1501
event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL;
1504
event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1508
event->crossing.focus = xevent->xcrossing.focus;
1509
event->crossing.state = xevent->xcrossing.state;
1513
/* We only care about focus events that indicate that _this_
1514
* window (not a ancestor or child) got or lost the focus
1518
g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
1519
xevent->xfocus.window,
1520
notify_details[xevent->xfocus.detail],
1521
notify_modes[xevent->xfocus.mode]));
1525
gboolean had_focus = HAS_FOCUS (toplevel);
1527
switch (xevent->xfocus.detail)
1529
case NotifyAncestor:
1531
/* When the focus moves from an ancestor of the window to
1532
* the window or a descendent of the window, *and* the
1533
* pointer is inside the window, then we were previously
1534
* receiving keystroke events in the has_pointer_focus
1535
* case and are now receiving them in the
1536
* has_focus_window case.
1538
if (toplevel->has_pointer &&
1539
xevent->xfocus.mode != NotifyGrab &&
1540
xevent->xfocus.mode != NotifyUngrab)
1541
toplevel->has_pointer_focus = FALSE;
1544
case NotifyNonlinear:
1545
case NotifyNonlinearVirtual:
1546
if (xevent->xfocus.mode != NotifyGrab &&
1547
xevent->xfocus.mode != NotifyUngrab)
1548
toplevel->has_focus_window = TRUE;
1549
/* We pretend that the focus moves to the grab
1550
* window, so we pay attention to NotifyGrab
1551
* NotifyUngrab, and ignore NotifyWhileGrabbed
1553
if (xevent->xfocus.mode != NotifyWhileGrabbed)
1554
toplevel->has_focus = TRUE;
1557
/* The X server sends NotifyPointer/NotifyGrab,
1558
* but the pointer focus is ignored while a
1561
if (xevent->xfocus.mode != NotifyGrab &&
1562
xevent->xfocus.mode != NotifyUngrab)
1563
toplevel->has_pointer_focus = TRUE;
1565
case NotifyInferior:
1566
case NotifyPointerRoot:
1567
case NotifyDetailNone:
1571
if (HAS_FOCUS (toplevel) != had_focus)
1572
generate_focus_event (window, TRUE);
1577
g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
1578
xevent->xfocus.window,
1579
notify_details[xevent->xfocus.detail],
1580
notify_modes[xevent->xfocus.mode]));
1584
gboolean had_focus = HAS_FOCUS (toplevel);
1586
switch (xevent->xfocus.detail)
1588
case NotifyAncestor:
1590
/* When the focus moves from the window or a descendent
1591
* of the window to an ancestor of the window, *and* the
1592
* pointer is inside the window, then we were previously
1593
* receiving keystroke events in the has_focus_window
1594
* case and are now receiving them in the
1595
* has_pointer_focus case.
1597
if (toplevel->has_pointer &&
1598
xevent->xfocus.mode != NotifyGrab &&
1599
xevent->xfocus.mode != NotifyUngrab)
1600
toplevel->has_pointer_focus = TRUE;
1603
case NotifyNonlinear:
1604
case NotifyNonlinearVirtual:
1605
if (xevent->xfocus.mode != NotifyGrab &&
1606
xevent->xfocus.mode != NotifyUngrab)
1607
toplevel->has_focus_window = FALSE;
1608
if (xevent->xfocus.mode != NotifyWhileGrabbed)
1609
toplevel->has_focus = FALSE;
1612
if (xevent->xfocus.mode != NotifyGrab &&
1613
xevent->xfocus.mode != NotifyUngrab)
1614
toplevel->has_pointer_focus = FALSE;
1616
case NotifyInferior:
1617
case NotifyPointerRoot:
1618
case NotifyDetailNone:
1622
if (HAS_FOCUS (toplevel) != had_focus)
1623
generate_focus_event (window, FALSE);
1628
/* gdk_keyboard_grab() causes following events. These events confuse
1629
* the XIM focus, so ignore them.
1631
if (xevent->xfocus.mode == NotifyGrab ||
1632
xevent->xfocus.mode == NotifyUngrab)
1638
g_message ("keymap notify"));
1640
/* Not currently handled */
1646
g_message ("expose:\t\twindow: %ld %d x,y: %d %d w,h: %d %d%s",
1647
xevent->xexpose.window, xevent->xexpose.count,
1648
xevent->xexpose.x, xevent->xexpose.y,
1649
xevent->xexpose.width, xevent->xexpose.height,
1650
event->any.send_event ? " (send)" : ""));
1652
if (window_private == NULL)
1659
GdkRectangle expose_rect;
1661
expose_rect.x = xevent->xexpose.x;
1662
expose_rect.y = xevent->xexpose.y;
1663
expose_rect.width = xevent->xexpose.width;
1664
expose_rect.height = xevent->xexpose.height;
1666
_gdk_window_process_expose (window, xevent->xexpose.serial, &expose_rect);
1672
case GraphicsExpose:
1674
GdkRectangle expose_rect;
1677
g_message ("graphics expose:\tdrawable: %ld",
1678
xevent->xgraphicsexpose.drawable));
1680
if (window_private == NULL)
1686
expose_rect.x = xevent->xgraphicsexpose.x;
1687
expose_rect.y = xevent->xgraphicsexpose.y;
1688
expose_rect.width = xevent->xgraphicsexpose.width;
1689
expose_rect.height = xevent->xgraphicsexpose.height;
1693
event->expose.type = GDK_EXPOSE;
1694
event->expose.area = expose_rect;
1695
event->expose.region = gdk_region_rectangle (&expose_rect);
1696
event->expose.window = window;
1697
event->expose.count = xevent->xgraphicsexpose.count;
1703
_gdk_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect);
1713
g_message ("no expose:\t\tdrawable: %ld",
1714
xevent->xnoexpose.drawable));
1716
event->no_expose.type = GDK_NO_EXPOSE;
1717
event->no_expose.window = window;
1721
case VisibilityNotify:
1722
#ifdef G_ENABLE_DEBUG
1723
if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
1724
switch (xevent->xvisibility.state)
1726
case VisibilityFullyObscured:
1727
g_message ("visibility notify:\twindow: %ld none",
1728
xevent->xvisibility.window);
1730
case VisibilityPartiallyObscured:
1731
g_message ("visibility notify:\twindow: %ld partial",
1732
xevent->xvisibility.window);
1734
case VisibilityUnobscured:
1735
g_message ("visibility notify:\twindow: %ld full",
1736
xevent->xvisibility.window);
1739
#endif /* G_ENABLE_DEBUG */
1741
if (window_private == NULL)
1747
event->visibility.type = GDK_VISIBILITY_NOTIFY;
1748
event->visibility.window = window;
1750
switch (xevent->xvisibility.state)
1752
case VisibilityFullyObscured:
1753
event->visibility.state = GDK_VISIBILITY_FULLY_OBSCURED;
1756
case VisibilityPartiallyObscured:
1757
event->visibility.state = GDK_VISIBILITY_PARTIAL;
1760
case VisibilityUnobscured:
1761
event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
1769
g_message ("create notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d parent: %ld ovr: %d",
1770
xevent->xcreatewindow.window,
1771
xevent->xcreatewindow.x,
1772
xevent->xcreatewindow.y,
1773
xevent->xcreatewindow.width,
1774
xevent->xcreatewindow.height,
1775
xevent->xcreatewindow.border_width,
1776
xevent->xcreatewindow.parent,
1777
xevent->xcreatewindow.override_redirect));
1778
/* not really handled */
1783
g_message ("destroy notify:\twindow: %ld",
1784
xevent->xdestroywindow.window));
1786
/* Ignore DestroyNotify from SubstructureNotifyMask */
1787
if (xevent->xdestroywindow.window == xevent->xdestroywindow.event)
1789
event->any.type = GDK_DESTROY;
1790
event->any.window = window;
1792
return_val = window_private && !GDK_WINDOW_DESTROYED (window);
1794
if (window && GDK_WINDOW_XID (window) != screen_x11->xroot_window)
1795
gdk_window_destroy_notify (window);
1804
g_message ("unmap notify:\t\twindow: %ld",
1805
xevent->xmap.window));
1807
event->any.type = GDK_UNMAP;
1808
event->any.window = window;
1810
/* If the WM supports the _NET_WM_STATE_HIDDEN hint, we do not want to
1811
* interpret UnmapNotify events as implying iconic state.
1812
* http://bugzilla.gnome.org/show_bug.cgi?id=590726.
1815
!gdk_x11_screen_supports_net_wm_hint (screen,
1816
gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN")))
1818
/* If we are shown (not withdrawn) and get an unmap, it means we were
1819
* iconified in the X sense. If we are withdrawn, and get an unmap, it
1820
* means we hid the window ourselves, so we will have already flipped
1821
* the iconified bit off.
1823
if (window && GDK_WINDOW_IS_MAPPED (window))
1824
gdk_synthesize_window_state (window,
1826
GDK_WINDOW_STATE_ICONIFIED);
1830
_gdk_xgrab_check_unmap (window, xevent->xany.serial);
1836
g_message ("map notify:\t\twindow: %ld",
1837
xevent->xmap.window));
1839
event->any.type = GDK_MAP;
1840
event->any.window = window;
1842
/* Unset iconified if it was set */
1843
if (window && (((GdkWindowObject*)window)->state & GDK_WINDOW_STATE_ICONIFIED))
1844
gdk_synthesize_window_state (window,
1845
GDK_WINDOW_STATE_ICONIFIED,
1850
case ReparentNotify:
1852
g_message ("reparent notify:\twindow: %ld x,y: %d %d parent: %ld ovr: %d",
1853
xevent->xreparent.window,
1854
xevent->xreparent.x,
1855
xevent->xreparent.y,
1856
xevent->xreparent.parent,
1857
xevent->xreparent.override_redirect));
1859
/* Not currently handled */
1863
case ConfigureNotify:
1865
g_message ("configure notify:\twindow: %ld x,y: %d %d w,h: %d %d b-w: %d above: %ld ovr: %d%s",
1866
xevent->xconfigure.window,
1867
xevent->xconfigure.x,
1868
xevent->xconfigure.y,
1869
xevent->xconfigure.width,
1870
xevent->xconfigure.height,
1871
xevent->xconfigure.border_width,
1872
xevent->xconfigure.above,
1873
xevent->xconfigure.override_redirect,
1876
: GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD
1877
? " (discarding child)"
1878
: xevent->xconfigure.event != xevent->xconfigure.window
1879
? " (discarding substructure)"
1881
if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
1883
window_private->width = xevent->xconfigure.width;
1884
window_private->height = xevent->xconfigure.height;
1886
_gdk_window_update_size (window);
1887
_gdk_x11_drawable_update_size (window_private->impl);
1888
_gdk_x11_screen_size_changed (screen, xevent);
1892
xevent->xconfigure.event == xevent->xconfigure.window &&
1893
!GDK_WINDOW_DESTROYED (window) &&
1894
window_private->input_window != NULL)
1895
_gdk_input_configure_event (&xevent->xconfigure, window);
1898
if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
1900
toplevel->current_counter_value = toplevel->pending_counter_value;
1901
XSyncIntToValue (&toplevel->pending_counter_value, 0);
1906
xevent->xconfigure.event != xevent->xconfigure.window ||
1907
GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
1908
GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
1912
event->configure.type = GDK_CONFIGURE;
1913
event->configure.window = window;
1914
event->configure.width = xevent->xconfigure.width;
1915
event->configure.height = xevent->xconfigure.height;
1917
if (!xevent->xconfigure.send_event &&
1918
!xevent->xconfigure.override_redirect &&
1919
!GDK_WINDOW_DESTROYED (window))
1923
Window child_window = 0;
1925
gdk_error_trap_push ();
1926
if (XTranslateCoordinates (GDK_DRAWABLE_XDISPLAY (window),
1927
GDK_DRAWABLE_XID (window),
1928
screen_x11->xroot_window,
1933
event->configure.x = tx;
1934
event->configure.y = ty;
1936
gdk_error_trap_pop ();
1940
event->configure.x = xevent->xconfigure.x;
1941
event->configure.y = xevent->xconfigure.y;
1943
window_private->x = event->configure.x;
1944
window_private->y = event->configure.y;
1945
window_private->width = xevent->xconfigure.width;
1946
window_private->height = xevent->xconfigure.height;
1948
_gdk_window_update_size (window);
1949
_gdk_x11_drawable_update_size (window_private->impl);
1951
if (window_private->resize_count >= 1)
1953
window_private->resize_count -= 1;
1955
if (window_private->resize_count == 0)
1956
_gdk_moveresize_configure_done (display, window);
1961
case PropertyNotify:
1963
g_message ("property notify:\twindow: %ld, atom(%ld): %s%s%s",
1964
xevent->xproperty.window,
1965
xevent->xproperty.atom,
1967
gdk_x11_get_xatom_name_for_display (display, xevent->xproperty.atom),
1970
if (window_private == NULL)
1976
/* We compare with the serial of the last time we mapped the
1977
* window to avoid refetching properties that we set ourselves
1980
xevent->xproperty.serial >= toplevel->map_serial)
1982
if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"))
1983
gdk_check_wm_state_changed (window);
1985
if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"))
1986
gdk_check_wm_desktop_changed (window);
1989
if (window_private->event_mask & GDK_PROPERTY_CHANGE_MASK)
1991
event->property.type = GDK_PROPERTY_NOTIFY;
1992
event->property.window = window;
1993
event->property.atom = gdk_x11_xatom_to_atom_for_display (display, xevent->xproperty.atom);
1994
event->property.time = xevent->xproperty.time;
1995
event->property.state = xevent->xproperty.state;
2002
case SelectionClear:
2004
g_message ("selection clear:\twindow: %ld",
2005
xevent->xproperty.window));
2007
if (_gdk_selection_filter_clear_event (&xevent->xselectionclear))
2009
event->selection.type = GDK_SELECTION_CLEAR;
2010
event->selection.window = window;
2011
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionclear.selection);
2012
event->selection.time = xevent->xselectionclear.time;
2019
case SelectionRequest:
2021
g_message ("selection request:\twindow: %ld",
2022
xevent->xproperty.window));
2024
event->selection.type = GDK_SELECTION_REQUEST;
2025
event->selection.window = window;
2026
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.selection);
2027
event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.target);
2028
event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselectionrequest.property);
2029
event->selection.requestor = xevent->xselectionrequest.requestor;
2030
event->selection.time = xevent->xselectionrequest.time;
2034
case SelectionNotify:
2036
g_message ("selection notify:\twindow: %ld",
2037
xevent->xproperty.window));
2040
event->selection.type = GDK_SELECTION_NOTIFY;
2041
event->selection.window = window;
2042
event->selection.selection = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.selection);
2043
event->selection.target = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.target);
2044
if (xevent->xselection.property == None)
2045
event->selection.property = GDK_NONE;
2047
event->selection.property = gdk_x11_xatom_to_atom_for_display (display, xevent->xselection.property);
2048
event->selection.time = xevent->xselection.time;
2052
case ColormapNotify:
2054
g_message ("colormap notify:\twindow: %ld",
2055
xevent->xcolormap.window));
2057
/* Not currently handled */
2064
GdkFilterReturn result = GDK_FILTER_CONTINUE;
2065
GdkAtom message_type = gdk_x11_xatom_to_atom_for_display (display, xevent->xclient.message_type);
2068
g_message ("client message:\twindow: %ld",
2069
xevent->xclient.window));
2071
tmp_list = display_x11->client_filters;
2074
GdkClientFilter *filter = tmp_list->data;
2075
tmp_list = tmp_list->next;
2077
if (filter->type == message_type)
2079
result = (*filter->function) (xevent, event, filter->data);
2080
if (result != GDK_FILTER_CONTINUE)
2087
case GDK_FILTER_REMOVE:
2090
case GDK_FILTER_TRANSLATE:
2093
case GDK_FILTER_CONTINUE:
2094
/* Send unknown ClientMessage's on to Gtk for it to use */
2095
if (window_private == NULL)
2101
event->client.type = GDK_CLIENT_EVENT;
2102
event->client.window = window;
2103
event->client.message_type = message_type;
2104
event->client.data_format = xevent->xclient.format;
2105
memcpy(&event->client.data, &xevent->xclient.data,
2106
sizeof(event->client.data));
2116
g_message ("mapping notify"));
2118
/* Let XLib know that there is a new keyboard mapping.
2120
XRefreshKeyboardMapping (&xevent->xmapping);
2121
_gdk_keymap_keys_changed (display);
2127
if (xevent->type == display_x11->xkb_event_type)
2129
XkbEvent *xkb_event = (XkbEvent *)xevent;
2131
switch (xkb_event->any.xkb_type)
2133
case XkbNewKeyboardNotify:
2135
_gdk_keymap_keys_changed (display);
2140
case XkbStateNotify:
2141
_gdk_keymap_state_changed (display, xevent);
2148
if (xevent->type - display_x11->xfixes_event_base == XFixesSelectionNotify)
2150
XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)xevent;
2152
_gdk_x11_screen_process_owner_change (screen, xevent);
2154
event->owner_change.type = GDK_OWNER_CHANGE;
2155
event->owner_change.window = window;
2156
event->owner_change.owner = selection_notify->owner;
2157
event->owner_change.reason = selection_notify->subtype;
2158
event->owner_change.selection =
2159
gdk_x11_xatom_to_atom_for_display (display,
2160
selection_notify->selection);
2161
event->owner_change.time = selection_notify->timestamp;
2162
event->owner_change.selection_time = selection_notify->selection_timestamp;
2169
if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify ||
2170
xevent->type - display_x11->xrandr_event_base == RRNotify)
2173
_gdk_x11_screen_size_changed (screen, xevent);
2177
#if defined(HAVE_XCOMPOSITE) && defined (HAVE_XDAMAGE) && defined (HAVE_XFIXES)
2178
if (display_x11->have_xdamage && window_private && window_private->composited &&
2179
xevent->type == display_x11->xdamage_event_base + XDamageNotify &&
2180
((XDamageNotifyEvent *) xevent)->damage == window_impl->damage)
2182
XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent;
2183
XserverRegion repair;
2186
rect.x = window_private->x + damage_event->area.x;
2187
rect.y = window_private->y + damage_event->area.y;
2188
rect.width = damage_event->area.width;
2189
rect.height = damage_event->area.height;
2191
repair = XFixesCreateRegion (display_x11->xdisplay,
2192
&damage_event->area, 1);
2193
XDamageSubtract (display_x11->xdisplay,
2194
window_impl->damage,
2196
XFixesDestroyRegion (display_x11->xdisplay, repair);
2198
if (window_private->parent != NULL)
2199
_gdk_window_process_expose (GDK_WINDOW (window_private->parent),
2200
damage_event->serial, &rect);
2207
/* something else - (e.g., a Xinput event) */
2209
if (window_private &&
2210
!GDK_WINDOW_DESTROYED (window_private) &&
2211
window_private->input_window)
2212
return_val = _gdk_input_other_event (event, xevent, window);
2223
if (event->any.window)
2224
g_object_ref (event->any.window);
2225
if (((event->any.type == GDK_ENTER_NOTIFY) ||
2226
(event->any.type == GDK_LEAVE_NOTIFY)) &&
2227
(event->crossing.subwindow != NULL))
2228
g_object_ref (event->crossing.subwindow);
2232
/* Mark this event as having no resources to be freed */
2233
event->any.window = NULL;
2234
event->any.type = GDK_NOTHING;
2238
g_object_unref (window);
2243
static GdkFilterReturn
2244
gdk_wm_protocols_filter (GdkXEvent *xev,
2248
XEvent *xevent = (XEvent *)xev;
2249
GdkWindow *win = event->any.window;
2250
GdkDisplay *display;
2254
return GDK_FILTER_REMOVE;
2256
display = GDK_WINDOW_DISPLAY (win);
2257
atom = (Atom)xevent->xclient.data.l[0];
2259
if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
2261
/* The delete window request specifies a window
2262
* to delete. We don't actually destroy the
2263
* window because "it is only a request". (The
2264
* window might contain vital data that the
2265
* program does not want destroyed). Instead
2266
* the event is passed along to the program,
2267
* which should then destroy the window.
2270
g_message ("delete window:\t\twindow: %ld",
2271
xevent->xclient.window));
2273
event->any.type = GDK_DELETE;
2275
gdk_x11_window_set_user_time (win, xevent->xclient.data.l[1]);
2277
return GDK_FILTER_TRANSLATE;
2279
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
2281
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
2282
GdkWindowObject *private = (GdkWindowObject *)win;
2284
/* There is no way of knowing reliably whether we are viewable;
2285
* _gdk_x11_set_input_focus_safe() traps errors asynchronously.
2287
if (toplevel && private->accept_focus)
2288
_gdk_x11_set_input_focus_safe (display, toplevel->focus_window,
2290
xevent->xclient.data.l[1]);
2292
return GDK_FILTER_REMOVE;
2294
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
2295
!_gdk_x11_display_is_root_window (display,
2296
xevent->xclient.window))
2298
XClientMessageEvent xclient = xevent->xclient;
2300
xclient.window = GDK_WINDOW_XROOTWIN (win);
2301
XSendEvent (GDK_WINDOW_XDISPLAY (win),
2304
SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xclient);
2306
return GDK_FILTER_REMOVE;
2308
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
2309
GDK_DISPLAY_X11 (display)->use_sync)
2311
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
2315
XSyncIntsToValue (&toplevel->pending_counter_value,
2316
xevent->xclient.data.l[2],
2317
xevent->xclient.data.l[3]);
2320
return GDK_FILTER_REMOVE;
2323
return GDK_FILTER_CONTINUE;
2327
_gdk_events_queue (GdkDisplay *display)
2332
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
2334
while (!_gdk_event_queue_find_first(display) && XPending (xdisplay))
2336
XNextEvent (xdisplay, &xevent);
2338
switch (xevent.type)
2344
if (XFilterEvent (&xevent, None))
2348
event = gdk_event_new (GDK_NOTHING);
2350
event->any.window = NULL;
2351
event->any.send_event = xevent.xany.send_event ? TRUE : FALSE;
2353
((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2355
node = _gdk_event_queue_append (display, event);
2357
if (gdk_event_translate (display, event, &xevent, FALSE))
2359
((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2360
_gdk_windowing_got_event (display, node, event, xevent.xany.serial);
2364
_gdk_event_queue_remove_link (display, node);
2365
g_list_free_1 (node);
2366
gdk_event_free (event);
2372
gdk_event_prepare (GSource *source,
2375
GdkDisplay *display = ((GdkDisplaySource*)source)->display;
2378
GDK_THREADS_ENTER ();
2381
retval = (_gdk_event_queue_find_first (display) != NULL ||
2382
gdk_check_xpending (display));
2384
GDK_THREADS_LEAVE ();
2390
gdk_event_check (GSource *source)
2392
GdkDisplaySource *display_source = (GdkDisplaySource*)source;
2395
GDK_THREADS_ENTER ();
2397
if (display_source->event_poll_fd.revents & G_IO_IN)
2398
retval = (_gdk_event_queue_find_first (display_source->display) != NULL ||
2399
gdk_check_xpending (display_source->display));
2403
GDK_THREADS_LEAVE ();
2409
gdk_event_dispatch (GSource *source,
2410
GSourceFunc callback,
2413
GdkDisplay *display = ((GdkDisplaySource*)source)->display;
2416
GDK_THREADS_ENTER ();
2418
_gdk_events_queue (display);
2419
event = _gdk_event_unqueue (display);
2423
if (_gdk_event_func)
2424
(*_gdk_event_func) (event, _gdk_event_data);
2426
gdk_event_free (event);
2429
GDK_THREADS_LEAVE ();
2435
* gdk_event_send_client_message_for_display:
2436
* @display: the #GdkDisplay for the window where the message is to be sent.
2437
* @event: the #GdkEvent to send, which should be a #GdkEventClient.
2438
* @winid: the window to send the client message to.
2440
* On X11, sends an X ClientMessage event to a given window. On
2441
* Windows, sends a message registered with the name
2442
* GDK_WIN32_CLIENT_MESSAGE.
2444
* This could be used for communicating between different
2445
* applications, though the amount of data is limited to 20 bytes on
2446
* X11, and to just four bytes on Windows.
2448
* Returns: non-zero on success.
2453
gdk_event_send_client_message_for_display (GdkDisplay *display,
2455
GdkNativeWindow winid)
2459
g_return_val_if_fail(event != NULL, FALSE);
2461
/* Set up our event to send, with the exception of its target window */
2462
sev.xclient.type = ClientMessage;
2463
sev.xclient.display = GDK_DISPLAY_XDISPLAY (display);
2464
sev.xclient.format = event->client.data_format;
2465
sev.xclient.window = winid;
2466
memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data));
2467
sev.xclient.message_type = gdk_x11_atom_to_xatom_for_display (display, event->client.message_type);
2469
return _gdk_send_xevent (display, winid, False, NoEventMask, &sev);
2474
/* Sends a ClientMessage to all toplevel client windows */
2476
gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
2483
unsigned long nitems, after;
2484
unsigned char *data;
2485
Window *ret_children, ret_root, ret_parent;
2486
unsigned int ret_nchildren;
2487
gboolean send = FALSE;
2488
gboolean found = FALSE;
2489
gboolean result = FALSE;
2492
gdk_error_trap_push ();
2494
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid,
2495
gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"),
2496
0, 0, False, AnyPropertyType,
2497
&type, &format, &nitems, &after, &data) != Success)
2507
/* OK, we're all set, now let's find some windows to send this to */
2508
if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xid,
2509
&ret_root, &ret_parent,
2510
&ret_children, &ret_nchildren))
2513
for(i = 0; i < ret_nchildren; i++)
2514
if (gdk_event_send_client_message_to_all_recurse (display, xev, ret_children[i], level + 1))
2517
XFree (ret_children);
2520
if (send || (!found && (level == 1)))
2522
xev->xclient.window = xid;
2523
_gdk_send_xevent (display, xid, False, NoEventMask, xev);
2526
result = send || found;
2529
gdk_error_trap_pop ();
2535
* gdk_screen_broadcast_client_message:
2536
* @screen: the #GdkScreen where the event will be broadcasted.
2537
* @event: the #GdkEvent.
2539
* On X11, sends an X ClientMessage event to all toplevel windows on
2542
* Toplevel windows are determined by checking for the WM_STATE property,
2543
* as described in the Inter-Client Communication Conventions Manual (ICCCM).
2544
* If no windows are found with the WM_STATE property set, the message is
2545
* sent to all children of the root window.
2547
* On Windows, broadcasts a message registered with the name
2548
* GDK_WIN32_CLIENT_MESSAGE to all top-level windows. The amount of
2549
* data is limited to one long, i.e. four bytes.
2555
gdk_screen_broadcast_client_message (GdkScreen *screen,
2559
GdkWindow *root_window;
2561
g_return_if_fail (event != NULL);
2563
root_window = gdk_screen_get_root_window (screen);
2565
/* Set up our event to send, with the exception of its target window */
2566
sev.xclient.type = ClientMessage;
2567
sev.xclient.display = GDK_WINDOW_XDISPLAY (root_window);
2568
sev.xclient.format = event->client.data_format;
2569
memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data));
2570
sev.xclient.message_type =
2571
gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (root_window),
2572
event->client.message_type);
2574
gdk_event_send_client_message_to_all_recurse (gdk_screen_get_display (screen),
2576
GDK_WINDOW_XID (root_window),
2581
*--------------------------------------------------------------
2584
* Flushes the Xlib output buffer and then waits
2585
* until all requests have been received and processed
2586
* by the X server. The only real use for this function
2587
* is in dealing with XShm.
2595
*--------------------------------------------------------------
2601
GSList *tmp_list = _gdk_displays;
2605
XSync (GDK_DISPLAY_XDISPLAY (tmp_list->data), False);
2606
tmp_list = tmp_list->next;
2611
timestamp_predicate (Display *display,
2615
Window xwindow = GPOINTER_TO_UINT (arg);
2616
GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display);
2618
if (xevent->type == PropertyNotify &&
2619
xevent->xproperty.window == xwindow &&
2620
xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
2621
"GDK_TIMESTAMP_PROP"))
2628
* gdk_x11_get_server_time:
2629
* @window: a #GdkWindow, used for communication with the server.
2630
* The window must have GDK_PROPERTY_CHANGE_MASK in its
2631
* events mask or a hang will result.
2633
* Routine to get the current X server time stamp.
2635
* Return value: the time stamp.
2638
gdk_x11_get_server_time (GdkWindow *window)
2644
Atom timestamp_prop_atom;
2646
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2647
g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
2649
xdisplay = GDK_WINDOW_XDISPLAY (window);
2650
xwindow = GDK_WINDOW_XWINDOW (window);
2651
timestamp_prop_atom =
2652
gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
2653
"GDK_TIMESTAMP_PROP");
2655
XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
2656
timestamp_prop_atom,
2657
8, PropModeReplace, &c, 1);
2659
XIfEvent (xdisplay, &xevent,
2660
timestamp_predicate, GUINT_TO_POINTER(xwindow));
2662
return xevent.xproperty.time;
2666
fetch_net_wm_check_window (GdkScreen *screen)
2668
GdkScreenX11 *screen_x11;
2669
GdkDisplay *display;
2679
screen_x11 = GDK_SCREEN_X11 (screen);
2680
display = screen_x11->display;
2682
g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client);
2684
g_get_current_time (&tv);
2686
if (ABS (tv.tv_sec - screen_x11->last_wmspec_check_time) < 15)
2687
return; /* we've checked recently */
2689
screen_x11->last_wmspec_check_time = tv.tv_sec;
2692
XGetWindowProperty (screen_x11->xdisplay, screen_x11->xroot_window,
2693
gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"),
2694
0, G_MAXLONG, False, XA_WINDOW, &type, &format,
2695
&n_items, &bytes_after, &data);
2697
if (type != XA_WINDOW)
2704
xwindow = (Window *)data;
2706
if (screen_x11->wmspec_check_window == *xwindow)
2712
gdk_error_trap_push ();
2714
/* Find out if this WM goes away, so we can reset everything. */
2715
XSelectInput (screen_x11->xdisplay, *xwindow, StructureNotifyMask);
2716
gdk_display_sync (display);
2718
error = gdk_error_trap_pop ();
2721
screen_x11->wmspec_check_window = *xwindow;
2722
screen_x11->need_refetch_net_supported = TRUE;
2723
screen_x11->need_refetch_wm_name = TRUE;
2725
/* Careful, reentrancy */
2726
_gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
2728
else if (error == BadWindow)
2730
/* Leftover property, try again immediately, new wm may be starting up */
2731
screen_x11->last_wmspec_check_time = 0;
2738
* gdk_x11_screen_get_window_manager_name:
2739
* @screen: a #GdkScreen
2741
* Returns the name of the window manager for @screen.
2743
* Return value: the name of the window manager screen @screen, or
2744
* "unknown" if the window manager is unknown. The string is owned by GDK
2745
* and should not be freed.
2750
gdk_x11_screen_get_window_manager_name (GdkScreen *screen)
2752
GdkScreenX11 *screen_x11;
2754
screen_x11 = GDK_SCREEN_X11 (screen);
2756
if (!G_LIKELY (GDK_DISPLAY_X11 (screen_x11->display)->trusted_client))
2757
return screen_x11->window_manager_name;
2759
fetch_net_wm_check_window (screen);
2761
if (screen_x11->need_refetch_wm_name)
2763
/* Get the name of the window manager */
2764
screen_x11->need_refetch_wm_name = FALSE;
2766
g_free (screen_x11->window_manager_name);
2767
screen_x11->window_manager_name = g_strdup ("unknown");
2769
if (screen_x11->wmspec_check_window != None)
2779
gdk_error_trap_push ();
2781
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (screen_x11->display),
2782
screen_x11->wmspec_check_window,
2783
gdk_x11_get_xatom_by_name_for_display (screen_x11->display,
2785
0, G_MAXLONG, False,
2786
gdk_x11_get_xatom_by_name_for_display (screen_x11->display,
2789
&n_items, &bytes_after,
2792
gdk_display_sync (screen_x11->display);
2794
gdk_error_trap_pop ();
2798
g_free (screen_x11->window_manager_name);
2799
screen_x11->window_manager_name = g_strdup (name);
2805
return GDK_SCREEN_X11 (screen)->window_manager_name;
2808
typedef struct _NetWmSupportedAtoms NetWmSupportedAtoms;
2810
struct _NetWmSupportedAtoms
2817
cleanup_atoms(gpointer data)
2819
NetWmSupportedAtoms *supported_atoms = data;
2820
if (supported_atoms->atoms)
2821
XFree (supported_atoms->atoms);
2822
g_free (supported_atoms);
2826
* gdk_x11_screen_supports_net_wm_hint:
2827
* @screen: the relevant #GdkScreen.
2828
* @property: a property atom.
2830
* This function is specific to the X11 backend of GDK, and indicates
2831
* whether the window manager supports a certain hint from the
2832
* Extended Window Manager Hints Specification. You can find this
2834
* <ulink url="http://www.freedesktop.org">http://www.freedesktop.org</ulink>.
2836
* When using this function, keep in mind that the window manager
2837
* can change over time; so you shouldn't use this function in
2838
* a way that impacts persistent application state. A common bug
2839
* is that your application can start up before the window manager
2840
* does when the user logs in, and before the window manager starts
2841
* gdk_x11_screen_supports_net_wm_hint() will return %FALSE for every property.
2842
* You can monitor the window_manager_changed signal on #GdkScreen to detect
2843
* a window manager change.
2845
* Return value: %TRUE if the window manager supports @property
2850
gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
2854
GdkScreenX11 *screen_x11;
2855
NetWmSupportedAtoms *supported_atoms;
2856
GdkDisplay *display;
2858
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
2860
screen_x11 = GDK_SCREEN_X11 (screen);
2861
display = screen_x11->display;
2863
if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
2866
supported_atoms = g_object_get_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms");
2867
if (!supported_atoms)
2869
supported_atoms = g_new0 (NetWmSupportedAtoms, 1);
2870
g_object_set_data_full (G_OBJECT (screen), "gdk-net-wm-supported-atoms", supported_atoms, cleanup_atoms);
2873
fetch_net_wm_check_window (screen);
2875
if (screen_x11->wmspec_check_window == None)
2878
if (screen_x11->need_refetch_net_supported)
2880
/* WM has changed since we last got the supported list,
2887
screen_x11->need_refetch_net_supported = FALSE;
2889
if (supported_atoms->atoms)
2890
XFree (supported_atoms->atoms);
2892
supported_atoms->atoms = NULL;
2893
supported_atoms->n_atoms = 0;
2895
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window,
2896
gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTED"),
2897
0, G_MAXLONG, False, XA_ATOM, &type, &format,
2898
&supported_atoms->n_atoms, &bytes_after,
2899
(guchar **)&supported_atoms->atoms);
2901
if (type != XA_ATOM)
2905
if (supported_atoms->atoms == NULL)
2909
while (i < supported_atoms->n_atoms)
2911
if (supported_atoms->atoms[i] == gdk_x11_atom_to_xatom_for_display (display, property))
2921
* gdk_net_wm_supports:
2922
* @property: a property atom.
2924
* This function is specific to the X11 backend of GDK, and indicates
2925
* whether the window manager for the default screen supports a certain
2926
* hint from the Extended Window Manager Hints Specification. See
2927
* gdk_x11_screen_supports_net_wm_hint() for complete details.
2929
* Return value: %TRUE if the window manager supports @property
2931
* Deprecated:2.24: Use gdk_x11_screen_supports_net_wm_hint() instead
2934
gdk_net_wm_supports (GdkAtom property)
2936
return gdk_x11_screen_supports_net_wm_hint (gdk_screen_get_default (), property);
2941
gdk_xsettings_notify_cb (const char *name,
2942
XSettingsAction action,
2943
XSettingsSetting *setting,
2947
GdkScreen *screen = data;
2948
GdkScreenX11 *screen_x11 = data;
2951
if (screen_x11->xsettings_in_init)
2954
new_event.type = GDK_SETTING;
2955
new_event.setting.window = gdk_screen_get_root_window (screen);
2956
new_event.setting.send_event = FALSE;
2957
new_event.setting.name = NULL;
2959
for (i = 0; i < GDK_SETTINGS_N_ELEMENTS() ; i++)
2960
if (strcmp (GDK_SETTINGS_X_NAME (i), name) == 0)
2962
new_event.setting.name = (char*) GDK_SETTINGS_GDK_NAME (i);
2966
if (!new_event.setting.name)
2971
case XSETTINGS_ACTION_NEW:
2972
new_event.setting.action = GDK_SETTING_ACTION_NEW;
2974
case XSETTINGS_ACTION_CHANGED:
2975
new_event.setting.action = GDK_SETTING_ACTION_CHANGED;
2977
case XSETTINGS_ACTION_DELETED:
2978
new_event.setting.action = GDK_SETTING_ACTION_DELETED;
2982
gdk_event_put (&new_event);
2986
check_transform (const gchar *xsettings_name,
2990
if (!g_value_type_transformable (src_type, dest_type))
2992
g_warning ("Cannot transform xsetting %s of type %s to type %s\n",
2994
g_type_name (src_type),
2995
g_type_name (dest_type));
3003
* gdk_screen_get_setting:
3004
* @screen: the #GdkScreen where the setting is located
3005
* @name: the name of the setting
3006
* @value: location to store the value of the setting
3008
* Retrieves a desktop-wide setting such as double-click time
3009
* for the #GdkScreen @screen.
3011
* FIXME needs a list of valid settings here, or a link to
3014
* Returns: %TRUE if the setting existed and a value was stored
3015
* in @value, %FALSE otherwise.
3020
gdk_screen_get_setting (GdkScreen *screen,
3025
const char *xsettings_name = NULL;
3026
XSettingsResult result;
3027
XSettingsSetting *setting = NULL;
3028
GdkScreenX11 *screen_x11;
3029
gboolean success = FALSE;
3031
GValue tmp_val = { 0, };
3033
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
3035
screen_x11 = GDK_SCREEN_X11 (screen);
3037
for (i = 0; i < GDK_SETTINGS_N_ELEMENTS(); i++)
3038
if (strcmp (GDK_SETTINGS_GDK_NAME (i), name) == 0)
3040
xsettings_name = GDK_SETTINGS_X_NAME (i);
3044
if (!xsettings_name)
3047
result = xsettings_client_get_setting (screen_x11->xsettings_client,
3048
xsettings_name, &setting);
3049
if (result != XSETTINGS_SUCCESS)
3052
switch (setting->type)
3054
case XSETTINGS_TYPE_INT:
3055
if (check_transform (xsettings_name, G_TYPE_INT, G_VALUE_TYPE (value)))
3057
g_value_init (&tmp_val, G_TYPE_INT);
3058
g_value_set_int (&tmp_val, setting->data.v_int);
3059
g_value_transform (&tmp_val, value);
3064
case XSETTINGS_TYPE_STRING:
3065
if (check_transform (xsettings_name, G_TYPE_STRING, G_VALUE_TYPE (value)))
3067
g_value_init (&tmp_val, G_TYPE_STRING);
3068
g_value_set_string (&tmp_val, setting->data.v_string);
3069
g_value_transform (&tmp_val, value);
3074
case XSETTINGS_TYPE_COLOR:
3075
if (!check_transform (xsettings_name, GDK_TYPE_COLOR, G_VALUE_TYPE (value)))
3079
g_value_init (&tmp_val, GDK_TYPE_COLOR);
3082
color.red = setting->data.v_color.red;
3083
color.green = setting->data.v_color.green;
3084
color.blue = setting->data.v_color.blue;
3086
g_value_set_boxed (&tmp_val, &color);
3088
g_value_transform (&tmp_val, value);
3095
g_value_unset (&tmp_val);
3099
xsettings_setting_free (setting);
3104
return _gdk_x11_get_xft_setting (screen, name, value);
3107
static GdkFilterReturn
3108
gdk_xsettings_client_event_filter (GdkXEvent *xevent,
3112
GdkScreenX11 *screen = data;
3114
if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
3115
return GDK_FILTER_REMOVE;
3117
return GDK_FILTER_CONTINUE;
3121
gdk_xsettings_watch_cb (Window window,
3127
GdkScreen *screen = cb_data;
3129
gdkwin = gdk_window_lookup_for_display (gdk_screen_get_display (screen), window);
3134
g_object_ref (gdkwin);
3137
gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
3139
/* gdk_window_foreign_new_for_display() can fail and return NULL if the
3140
* window has already been destroyed.
3146
gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
3152
/* gdkwin should not be NULL here, since if starting the watch succeeded
3153
* we have a reference on the window. It might mean that the caller didn't
3154
* remove the watch when it got a DestroyNotify event. Or maybe the
3155
* caller ignored the return value when starting the watch failed.
3157
g_warning ("gdk_xsettings_watch_cb(): Couldn't find window to unwatch");
3161
gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
3162
g_object_unref (gdkwin);
3169
_gdk_windowing_event_data_copy (const GdkEvent *src,
3175
_gdk_windowing_event_data_free (GdkEvent *event)
3179
#define __GDK_EVENTS_X11_C__
3180
#include "gdkaliasdef.c"