void _gdk_x11_screen_set_window_scale (GdkX11Screen *x11_screen, gint scale) { GdkX11Display *x11_display = GDK_X11_DISPLAY (x11_screen->display); GList *toplevels, *l; GdkWindow *root; int i; if (x11_screen->window_scale == scale) return; x11_screen->window_scale = scale; root = x11_screen->root_window; GDK_WINDOW_IMPL_X11 (root->impl)->window_scale = scale; toplevels = gdk_screen_get_toplevel_windows (GDK_SCREEN (x11_screen)); for (l = toplevels; l != NULL; l = l->next) { GdkWindow *window = l->data; _gdk_x11_window_set_window_scale (window, scale); } for (i = 0; i < x11_display->monitors->len; i++) { GdkMonitor *monitor = GDK_MONITOR (x11_display->monitors->pdata[i]); gdk_monitor_set_scale_factor (monitor, scale); } g_signal_emit_by_name (GDK_SCREEN (x11_screen), "monitors-changed"); }
void _gdk_x11_screen_set_window_scale (GdkX11Screen *x11_screen, gint scale) { GList *toplevels, *l; GdkWindow *root; if (x11_screen->window_scale == scale) return; x11_screen->window_scale = scale; root = x11_screen->root_window; GDK_WINDOW_IMPL_X11 (root->impl)->window_scale = scale; toplevels = gdk_screen_get_toplevel_windows (GDK_SCREEN (x11_screen)); for (l = toplevels; l != NULL; l = l->next) { GdkWindow *window = l->data; _gdk_x11_window_set_window_scale (window, scale); } g_signal_emit_by_name (GDK_SCREEN (x11_screen), "monitors-changed"); }
void _gdk_x11_window_move_resize_child (GdkWindow *window, gint x, gint y, gint width, gint height) { GdkWindowImplX11 *impl; g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); impl = GDK_WINDOW_IMPL_X11 (window->impl); if (width * impl->window_scale > 65535 || height * impl->window_scale > 65535) { g_warning ("Native children wider or taller than 65535 pixels are not supported"); if (width * impl->window_scale > 65535) width = 65535 / impl->window_scale; if (height * impl->window_scale > 65535) height = 65535 / impl->window_scale; } window->x = x; window->y = y; window->width = width; window->height = height; /* We don't really care about origin overflow, because on overflow * the window won't be visible anyway and thus it will be shaped * to nothing */ _gdk_x11_window_tmp_unset_parent_bg (window); _gdk_x11_window_tmp_unset_bg (window, TRUE); XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), (window->x + window->parent->abs_x) * impl->window_scale, (window->y + window->parent->abs_y) * impl->window_scale, width * impl->window_scale, height * impl->window_scale); _gdk_x11_window_tmp_reset_parent_bg (window); _gdk_x11_window_tmp_reset_bg (window, TRUE); }
static gboolean gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, GdkDisplay *display, GdkEvent *event, XEvent *xevent) { GdkWindowImplX11 *impl; GdkX11DeviceManagerCore *device_manager; GdkWindow *window; gboolean return_val; int scale; GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator); window = get_event_window (translator, xevent); scale = 1; if (window) { if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window)) return FALSE; g_object_ref (window); impl = GDK_WINDOW_IMPL_X11 (window->impl); scale = impl->window_scale; } event->any.window = window; event->any.send_event = xevent->xany.send_event ? TRUE : FALSE; if (window && GDK_WINDOW_DESTROYED (window)) { if (xevent->type != DestroyNotify) { return_val = FALSE; goto done; } } if (window && (xevent->type == MotionNotify || xevent->type == ButtonRelease)) { if (_gdk_x11_moveresize_handle_event (xevent)) { return_val = FALSE; goto done; } } /* We do a "manual" conversion of the XEvent to a * GdkEvent. The structures are mostly the same so * the conversion is fairly straightforward. We also * optionally print debugging info regarding events * received. */ return_val = TRUE; switch (xevent->type) { case KeyPress: if (window == NULL) { return_val = FALSE; break; } translate_key_event (display, device_manager, event, xevent); set_user_time (window, event); break; case KeyRelease: if (window == NULL) { return_val = FALSE; break; } /* Emulate detectable auto-repeat by checking to see * if the next event is a key press with the same * keycode and timestamp, and if so, ignoring the event. */ if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display)) { XEvent next_event; XPeekEvent (xevent->xkey.display, &next_event); if (next_event.type == KeyPress && next_event.xkey.keycode == xevent->xkey.keycode && next_event.xkey.time == xevent->xkey.time) { return_val = FALSE; break; } } translate_key_event (display, device_manager, event, xevent); break; case ButtonPress: GDK_NOTE (EVENTS, g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); if (window == NULL) { return_val = FALSE; break; } /* If we get a ButtonPress event where the button is 4 or 5, it's a Scroll event */ switch (xevent->xbutton.button) { case 4: /* up */ case 5: /* down */ case 6: /* left */ case 7: /* right */ event->scroll.type = GDK_SCROLL; if (xevent->xbutton.button == 4) event->scroll.direction = GDK_SCROLL_UP; else if (xevent->xbutton.button == 5) event->scroll.direction = GDK_SCROLL_DOWN; else if (xevent->xbutton.button == 6) event->scroll.direction = GDK_SCROLL_LEFT; else event->scroll.direction = GDK_SCROLL_RIGHT; event->scroll.window = window; event->scroll.time = xevent->xbutton.time; event->scroll.x = (gdouble) xevent->xbutton.x / scale; event->scroll.y = (gdouble) xevent->xbutton.y / scale; event->scroll.x_root = (gdouble) xevent->xbutton.x_root / scale; event->scroll.y_root = (gdouble) xevent->xbutton.y_root / scale; event->scroll.state = (GdkModifierType) xevent->xbutton.state; event->scroll.device = device_manager->core_pointer; event->scroll.delta_x = 0; event->scroll.delta_y = 0; if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } break; default: event->button.type = GDK_BUTTON_PRESS; event->button.window = window; event->button.time = xevent->xbutton.time; event->button.x = (gdouble) xevent->xbutton.x / scale; event->button.y = (gdouble) xevent->xbutton.y / scale; event->button.x_root = (gdouble) xevent->xbutton.x_root / scale; event->button.y_root = (gdouble) xevent->xbutton.y_root / scale; event->button.axes = NULL; event->button.state = (GdkModifierType) xevent->xbutton.state; event->button.button = xevent->xbutton.button; event->button.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) return_val = FALSE; break; } set_user_time (window, event); break; case ButtonRelease: GDK_NOTE (EVENTS, g_message ("button release:\twindow: %ld x,y: %d %d button: %d", xevent->xbutton.window, xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.button)); if (window == NULL) { return_val = FALSE; break; } /* We treat button presses as scroll wheel events, so ignore the release */ if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 || xevent->xbutton.button == 6 || xevent->xbutton.button == 7) { return_val = FALSE; break; } event->button.type = GDK_BUTTON_RELEASE; event->button.window = window; event->button.time = xevent->xbutton.time; event->button.x = (gdouble) xevent->xbutton.x / scale; event->button.y = (gdouble) xevent->xbutton.y / scale; event->button.x_root = (gdouble) xevent->xbutton.x_root / scale; event->button.y_root = (gdouble) xevent->xbutton.y_root / scale; event->button.axes = NULL; event->button.state = (GdkModifierType) xevent->xbutton.state; event->button.button = xevent->xbutton.button; event->button.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) return_val = FALSE; break; case MotionNotify: GDK_NOTE (EVENTS, g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s", xevent->xmotion.window, xevent->xmotion.x, xevent->xmotion.y, (xevent->xmotion.is_hint) ? "true" : "false")); if (window == NULL) { return_val = FALSE; break; } event->motion.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = xevent->xmotion.time; event->motion.x = (gdouble) xevent->xmotion.x / scale; event->motion.y = (gdouble) xevent->xmotion.y / scale; event->motion.x_root = (gdouble) xevent->xmotion.x_root / scale; event->motion.y_root = (gdouble) xevent->xmotion.y_root / scale; event->motion.axes = NULL; event->motion.state = (GdkModifierType) xevent->xmotion.state; event->motion.is_hint = xevent->xmotion.is_hint; event->motion.device = device_manager->core_pointer; if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } break; case EnterNotify: GDK_NOTE (EVENTS, g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); if (window == NULL) { return_val = FALSE; break; } if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } event->crossing.type = GDK_ENTER_NOTIFY; event->crossing.window = window; gdk_event_set_device (event, device_manager->core_pointer); /* If the subwindow field of the XEvent is non-NULL, then * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; event->crossing.x = (gdouble) xevent->xcrossing.x / scale; event->crossing.y = (gdouble) xevent->xcrossing.y / scale; event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale; event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale; event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); event->crossing.focus = xevent->xcrossing.focus; event->crossing.state = xevent->xcrossing.state; break; case LeaveNotify: GDK_NOTE (EVENTS, g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld", xevent->xcrossing.window, xevent->xcrossing.detail, xevent->xcrossing.subwindow)); if (window == NULL) { return_val = FALSE; break; } if (!set_screen_from_root (display, event, xevent->xbutton.root)) { return_val = FALSE; break; } event->crossing.type = GDK_LEAVE_NOTIFY; event->crossing.window = window; gdk_event_set_device (event, device_manager->core_pointer); /* If the subwindow field of the XEvent is non-NULL, then * lookup the corresponding GdkWindow. */ if (xevent->xcrossing.subwindow != None) event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow); else event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; event->crossing.x = (gdouble) xevent->xcrossing.x / scale; event->crossing.y = (gdouble) xevent->xcrossing.y / scale; event->crossing.x_root = (gdouble) xevent->xcrossing.x_root / scale; event->crossing.y_root = (gdouble) xevent->xcrossing.y_root / scale; event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode); event->crossing.detail = translate_notify_type (xevent->xcrossing.detail); event->crossing.focus = xevent->xcrossing.focus; event->crossing.state = xevent->xcrossing.state; break; case FocusIn: case FocusOut: if (window) _gdk_device_manager_core_handle_focus (window, xevent->xfocus.window, device_manager->core_keyboard, NULL, xevent->type == FocusIn, xevent->xfocus.detail, xevent->xfocus.mode); return_val = FALSE; break; default: return_val = FALSE; } done: if (return_val) { if (event->any.window) g_object_ref (event->any.window); if (((event->any.type == GDK_ENTER_NOTIFY) || (event->any.type == GDK_LEAVE_NOTIFY)) && (event->crossing.subwindow != NULL)) g_object_ref (event->crossing.subwindow); } else { /* Mark this event as having no resources to be freed */ event->any.window = NULL; event->any.type = GDK_NOTHING; } if (window) g_object_unref (window); return return_val; }