📄 gdkevents-x11.c
字号:
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 voidgdk_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 voidgenerate_focus_event (GdkWindow *window, gboolean in){ GdkEvent event; event.type = GDK_FOCUS_CHANGE; event.focus_change.window = window; event.focus_change.send_event = FALSE; event.focus_change.in = in; gdk_event_put (&event);}static voidset_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);}static voidtranslate_key_event (GdkDisplay *display, GdkEvent *event, XEvent *xevent){ GdkKeymap *keymap = gdk_keymap_get_for_display (display); gunichar c = 0; guchar buf[7]; event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE; event->key.time = xevent->xkey.time; event->key.state = (GdkModifierType) xevent->xkey.state; event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state); event->key.hardware_keycode = xevent->xkey.keycode; event->key.keyval = GDK_VoidSymbol; gdk_keymap_translate_keyboard_state (keymap, event->key.hardware_keycode, event->key.state, event->key.group, &event->key.keyval, NULL, NULL, NULL); /* Fill in event->string crudely, since various programs * depend on it. */ event->key.string = NULL; if (event->key.keyval != GDK_VoidSymbol) c = gdk_keyval_to_unicode (event->key.keyval); if (c) { gsize bytes_written; gint len; /* Apply the control key - Taken from Xlib */ if (event->key.state & GDK_CONTROL_MASK) { if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F; else if (c == '2') { event->key.string = g_memdup ("\0\0", 2); event->key.length = 1; buf[0] = '\0'; goto out; } else if (c >= '3' && c <= '7') c -= ('3' - '\033'); else if (c == '8') c = '\177'; else if (c == '/') c = '_' & 0x1F; } len = g_unichar_to_utf8 (c, buf); buf[len] = '\0'; event->key.string = g_locale_from_utf8 (buf, len, NULL, &bytes_written, NULL); if (event->key.string) event->key.length = bytes_written; } else if (event->key.keyval == GDK_Escape) { event->key.length = 1; event->key.string = g_strdup ("\033"); } else if (event->key.keyval == GDK_Return || event->key.keyval == GDK_KP_Enter) { event->key.length = 1; event->key.string = g_strdup ("\r"); } if (!event->key.string) { event->key.length = 0; event->key.string = g_strdup (""); } out:#ifdef G_ENABLE_DEBUG if (_gdk_debug_flags & GDK_DEBUG_EVENTS) { g_message ("%s:\t\twindow: %ld key: %12s %d", event->type == GDK_KEY_PRESS ? "key press " : "key release", xevent->xkey.window, event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)", event->key.keyval); if (event->key.length > 0) g_message ("\t\tlength: %4d string: \"%s\"", 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 **/voidgdk_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 voidget_real_window (GdkDisplay *display, XEvent *event, Window *event_window, Window *filter_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; for (tmp_list = display_x11->event_types; tmp_list; tmp_list = tmp_list->next) { GdkEventTypeX11 *event_type = tmp_list->data; 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; }}#ifdef G_ENABLE_DEBUGstatic const char notify_modes[][19] = { "NotifyNormal", "NotifyGrab", "NotifyUngrab", "NotifyWhileGrabbed"};static const char notify_details[][23] = { "NotifyAncestor", "NotifyVirtual", "NotifyInferior", "NotifyNonlinear", "NotifyNonlinearVirtual", "NotifyPointer", "NotifyPointerRoot", "NotifyDetailNone"};#endifstatic voidset_user_time (GdkWindow *window, GdkEvent *event){ g_return_if_fail (event != NULL); window = gdk_window_get_toplevel (event->client.window); g_return_if_fail (GDK_IS_WINDOW (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 gbooleangdk_event_translate (GdkDisplay *display, GdkEvent *event, XEvent *xevent, gboolean return_exposes){ GdkWindow *window; GdkWindowObject *window_private; GdkWindow *filter_window; GdkWindowImplX11 *window_impl = NULL; 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, filter_xwindow; return_val = FALSE; /* init these, since the done: block uses them */ window = NULL; window_private = NULL; event->any.window = NULL; if (_gdk_default_filters) { /* Apply global filters */ GdkFilterReturn result; result = gdk_event_apply_filters (xevent, event, _gdk_default_filters); if (result != GDK_FILTER_CONTINUE) { return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; goto done; } } /* Find the GdkWindow that this event relates to. * Basically this means substructure events * are reported same as structure events */ 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_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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -