diff --git a/gdk/x11/gdkdevice-core-x11.c b/gdk/x11/gdkdevice-core-x11.c index 0c6ed7f31a..e21339dac0 100644 --- a/gdk/x11/gdkdevice-core-x11.c +++ b/gdk/x11/gdkdevice-core-x11.c @@ -135,10 +135,12 @@ gdk_x11_device_core_get_history (GdkDevice *device, XTimeCoord *xcoords; GdkTimeCoord **coords; GdkWindow *impl_window; + GdkWindowImplX11 *impl; int tmp_n_events; int i, j; impl_window = _gdk_window_get_impl_window (window); + impl = GDK_WINDOW_IMPL_X11 (impl_window->impl); xcoords = XGetMotionEvents (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (impl_window), start, stop, &tmp_n_events); @@ -149,11 +151,13 @@ gdk_x11_device_core_get_history (GdkDevice *device, for (i = 0, j = 0; i < tmp_n_events; i++) { - if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y)) + if (impl_coord_in_window (window, + xcoords[i].x / impl->window_scale, + xcoords[i].y / impl->window_scale)) { coords[j]->time = xcoords[i].time; - coords[j]->axes[0] = xcoords[i].x - window->abs_x; - coords[j]->axes[1] = xcoords[i].y - window->abs_y; + coords[j]->axes[0] = (double)xcoords[i].x / impl->window_scale - window->abs_x; + coords[j]->axes[1] = (double)xcoords[i].y / impl->window_scale - window->abs_y; j++; } } @@ -194,6 +198,7 @@ gdk_x11_device_core_get_state (GdkDevice *device, { gint x_int, y_int; + /* TODO: This rounds the coords, should use double */ gdk_window_get_device_position (window, device, &x_int, &y_int, mask); if (axes) @@ -232,7 +237,9 @@ gdk_x11_device_core_warp (GdkDevice *device, xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device)); dest = GDK_WINDOW_XID (gdk_screen_get_root_window (screen)); - XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y); + XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, + x * GDK_X11_SCREEN (screen)->window_scale, + y * GDK_X11_SCREEN (screen)->window_scale); } static void @@ -246,6 +253,7 @@ gdk_x11_device_core_query_state (GdkDevice *device, gint *win_y, GdkModifierType *mask) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); GdkDisplay *display; GdkScreen *default_screen; Window xroot_window, xchild_window; @@ -291,16 +299,16 @@ gdk_x11_device_core_query_state (GdkDevice *device, *child_window = gdk_x11_window_lookup_for_display (display, xchild_window); if (root_x) - *root_x = xroot_x; + *root_x = xroot_x / impl->window_scale; if (root_y) - *root_y = xroot_y; + *root_y = xroot_y / impl->window_scale; if (win_x) - *win_x = xwin_x; + *win_x = xwin_x / impl->window_scale; if (win_y) - *win_y = xwin_y; + *win_y = xwin_y / impl->window_scale; if (mask) *mask = xmask; @@ -413,6 +421,7 @@ gdk_x11_device_core_window_at_position (GdkDevice *device, GdkModifierType *mask, gboolean get_toplevel) { + GdkWindowImplX11 *impl; GdkDisplay *display; GdkScreen *screen; Display *xdisplay; @@ -464,6 +473,7 @@ gdk_x11_device_core_window_at_position (GdkDevice *device, for (list = toplevels; list != NULL; list = g_list_next (list)) { window = GDK_WINDOW (list->data); + impl = GDK_WINDOW_IMPL_X11 (window->impl); xwindow = GDK_WINDOW_XID (window); gdk_x11_display_error_trap_push (display); XQueryPointer (xdisplay, xwindow, @@ -479,7 +489,7 @@ gdk_x11_device_core_window_at_position (GdkDevice *device, break; } gdk_window_get_geometry (window, NULL, NULL, &width, &height); - if (winx >= 0 && winy >= 0 && winx < width && winy < height) + if (winx >= 0 && winy >= 0 && winx < width * impl->window_scale && winy < height * impl->window_scale) { /* A childless toplevel, or below another window? */ XSetWindowAttributes attributes; @@ -532,12 +542,15 @@ gdk_x11_device_core_window_at_position (GdkDevice *device, gdk_x11_display_ungrab (display); window = gdk_x11_window_lookup_for_display (display, last); + impl = NULL; + if (window) + impl = GDK_WINDOW_IMPL_X11 (window->impl); if (win_x) - *win_x = (window) ? xwin_x : -1; + *win_x = (window) ? xwin_x / impl->window_scale : -1; if (win_y) - *win_y = (window) ? xwin_y : -1; + *win_y = (window) ? xwin_y / impl->window_scale : -1; if (mask) *mask = xmask; diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c index 9755a06d47..4f85ba1703 100644 --- a/gdk/x11/gdkdevice-xi2.c +++ b/gdk/x11/gdkdevice-xi2.c @@ -303,7 +303,9 @@ gdk_x11_device_xi2_warp (GdkDevice *device, XIWarpPointer (GDK_SCREEN_XDISPLAY (screen), device_xi2->device_id, None, dest, - 0, 0, 0, 0, x, y); + 0, 0, 0, 0, + x * GDK_X11_SCREEN(screen)->window_scale, + y * GDK_X11_SCREEN(screen)->window_scale); } static void @@ -317,6 +319,7 @@ gdk_x11_device_xi2_query_state (GdkDevice *device, gint *win_y, GdkModifierType *mask) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device); GdkDisplay *display; GdkScreen *default_screen; @@ -381,16 +384,16 @@ gdk_x11_device_xi2_query_state (GdkDevice *device, *child_window = gdk_x11_window_lookup_for_display (display, xchild_window); if (root_x) - *root_x = (gint) xroot_x; + *root_x = (gint) (xroot_x / impl->window_scale); if (root_y) - *root_y = (gint) xroot_y; + *root_y = (gint) (xroot_y / impl->window_scale); if (win_x) - *win_x = (gint) xwin_x; + *win_x = (gint) (xwin_x / impl->window_scale); if (win_y) - *win_y = (gint) xwin_y; + *win_y = (gint) (xwin_y / impl->window_scale); if (mask) *mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state); @@ -479,6 +482,7 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device, GdkModifierType *mask, gboolean get_toplevel) { + GdkWindowImplX11 *impl; GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device); GdkDisplay *display; GdkScreen *screen; @@ -624,12 +628,15 @@ gdk_x11_device_xi2_window_at_position (GdkDevice *device, gdk_x11_display_ungrab (display); window = gdk_x11_window_lookup_for_display (display, last); + impl = NULL; + if (window) + impl = GDK_WINDOW_IMPL_X11 (window->impl); if (win_x) - *win_x = (window) ? (gint) xwin_x : -1; + *win_x = (window) ? (gint) (xwin_x / impl->window_scale) : -1; if (win_y) - *win_y = (window) ? (gint) xwin_y : -1; + *win_y = (window) ? (gint) (xwin_y / impl->window_scale) : -1; if (mask) *mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state); diff --git a/gdk/x11/gdkdevicemanager-core-x11.c b/gdk/x11/gdkdevicemanager-core-x11.c index 0e49fb76af..dffef969ff 100644 --- a/gdk/x11/gdkdevicemanager-core-x11.c +++ b/gdk/x11/gdkdevicemanager-core-x11.c @@ -332,9 +332,11 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, 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); @@ -342,14 +344,18 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *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; @@ -458,10 +464,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, event->scroll.window = window; event->scroll.time = xevent->xbutton.time; - event->scroll.x = (gdouble) xevent->xbutton.x; - event->scroll.y = (gdouble) xevent->xbutton.y; - event->scroll.x_root = (gdouble) xevent->xbutton.x_root; - event->scroll.y_root = (gdouble) xevent->xbutton.y_root; + 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; @@ -480,10 +486,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, event->button.type = GDK_BUTTON_PRESS; event->button.window = window; event->button.time = xevent->xbutton.time; - event->button.x = (gdouble) xevent->xbutton.x; - event->button.y = (gdouble) xevent->xbutton.y; - event->button.x_root = (gdouble) xevent->xbutton.x_root; - event->button.y_root = (gdouble) xevent->xbutton.y_root; + 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; @@ -523,10 +529,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, event->button.type = GDK_BUTTON_RELEASE; event->button.window = window; event->button.time = xevent->xbutton.time; - event->button.x = (gdouble) xevent->xbutton.x; - event->button.y = (gdouble) xevent->xbutton.y; - event->button.x_root = (gdouble) xevent->xbutton.x_root; - event->button.y_root = (gdouble) xevent->xbutton.y_root; + 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; @@ -553,10 +559,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, event->motion.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = xevent->xmotion.time; - event->motion.x = (gdouble) xevent->xmotion.x; - event->motion.y = (gdouble) xevent->xmotion.y; - event->motion.x_root = (gdouble) xevent->xmotion.x_root; - event->motion.y_root = (gdouble) xevent->xmotion.y_root; + 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; @@ -602,10 +608,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; - event->crossing.x = (gdouble) xevent->xcrossing.x; - event->crossing.y = (gdouble) xevent->xcrossing.y; - event->crossing.x_root = (gdouble) xevent->xcrossing.x_root; - event->crossing.y_root = (gdouble) xevent->xcrossing.y_root; + 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); @@ -646,10 +652,10 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator, event->crossing.subwindow = NULL; event->crossing.time = xevent->xcrossing.time; - event->crossing.x = (gdouble) xevent->xcrossing.x; - event->crossing.y = (gdouble) xevent->xcrossing.y; - event->crossing.x_root = (gdouble) xevent->xcrossing.x_root; - event->crossing.y_root = (gdouble) xevent->xcrossing.y_root; + 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); diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 7b8ce7617d..0584eacb3a 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -1115,6 +1115,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, XGenericEventCookie *cookie; gboolean return_val = TRUE; GdkWindow *window; + GdkWindowImplX11 *impl; + int scale; XIEvent *ev; device_manager = (GdkX11DeviceManagerXI2 *) translator; @@ -1136,6 +1138,13 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, if (window && GDK_WINDOW_DESTROYED (window)) return FALSE; + scale = 1; + if (window) + { + impl = GDK_WINDOW_IMPL_X11 (window->impl); + scale = impl->window_scale; + } + if (ev->evtype == XI_Motion || ev->evtype == XI_ButtonRelease) { @@ -1232,10 +1241,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->scroll.window = window; event->scroll.time = xev->time; - event->scroll.x = (gdouble) xev->event_x; - event->scroll.y = (gdouble) xev->event_y; - event->scroll.x_root = (gdouble) xev->root_x; - event->scroll.y_root = (gdouble) xev->root_y; + event->scroll.x = (gdouble) xev->event_x / scale; + event->scroll.y = (gdouble) xev->event_y / scale; + event->scroll.x_root = (gdouble) xev->root_x / scale; + event->scroll.y_root = (gdouble) xev->root_y / scale; event->scroll.delta_x = 0; event->scroll.delta_y = 0; @@ -1259,10 +1268,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->button.window = window; event->button.time = xev->time; - event->button.x = (gdouble) xev->event_x; - event->button.y = (gdouble) xev->event_y; - event->button.x_root = (gdouble) xev->root_x; - event->button.y_root = (gdouble) xev->root_y; + event->button.x = (gdouble) xev->event_x / scale; + event->button.y = (gdouble) xev->event_y / scale; + event->button.x_root = (gdouble) xev->root_x / scale; + event->button.y_root = (gdouble) xev->root_y / scale; event->button.device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (xev->deviceid)); @@ -1350,10 +1359,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->scroll.window = window; event->scroll.time = xev->time; - event->scroll.x = (gdouble) xev->event_x; - event->scroll.y = (gdouble) xev->event_y; - event->scroll.x_root = (gdouble) xev->root_x; - event->scroll.y_root = (gdouble) xev->root_y; + event->scroll.x = (gdouble) xev->event_x / scale; + event->scroll.y = (gdouble) xev->event_y / scale; + event->scroll.x_root = (gdouble) xev->root_x / scale; + event->scroll.y_root = (gdouble) xev->root_y / scale; event->scroll.delta_x = delta_x; event->scroll.delta_y = delta_y; @@ -1367,10 +1376,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->motion.type = GDK_MOTION_NOTIFY; event->motion.window = window; event->motion.time = xev->time; - event->motion.x = (gdouble) xev->event_x; - event->motion.y = (gdouble) xev->event_y; - event->motion.x_root = (gdouble) xev->root_x; - event->motion.y_root = (gdouble) xev->root_y; + event->motion.x = (gdouble) xev->event_x / scale; + event->motion.y = (gdouble) xev->event_y / scale; + event->motion.x_root = (gdouble) xev->root_x / scale; + event->motion.y_root = (gdouble) xev->root_y / scale; event->motion.device = device; gdk_event_set_source_device (event, source_device); @@ -1423,10 +1432,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->touch.window = window; event->touch.time = xev->time; - event->touch.x = (gdouble) xev->event_x; - event->touch.y = (gdouble) xev->event_y; - event->touch.x_root = (gdouble) xev->root_x; - event->touch.y_root = (gdouble) xev->root_y; + event->touch.x = (gdouble) xev->event_x / scale; + event->touch.y = (gdouble) xev->event_y / scale; + event->touch.x_root = (gdouble) xev->root_x / scale; + event->touch.y_root = (gdouble) xev->root_y / scale; event->touch.device = g_hash_table_lookup (device_manager->id_table, GUINT_TO_POINTER (xev->deviceid)); @@ -1492,10 +1501,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->touch.sequence = GUINT_TO_POINTER (xev->detail); event->touch.type = GDK_TOUCH_UPDATE; event->touch.time = xev->time; - event->touch.x = (gdouble) xev->event_x; - event->touch.y = (gdouble) xev->event_y; - event->touch.x_root = (gdouble) xev->root_x; - event->touch.y_root = (gdouble) xev->root_y; + event->touch.x = (gdouble) xev->event_x / scale; + event->touch.y = (gdouble) xev->event_y / scale; + event->touch.x_root = (gdouble) xev->root_x / scale; + event->touch.y_root = (gdouble) xev->root_y / scale; event->touch.device = g_hash_table_lookup (device_manager->id_table, GINT_TO_POINTER (xev->deviceid)); @@ -1540,10 +1549,10 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, event->crossing.type = (ev->evtype == XI_Enter) ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY; - event->crossing.x = (gdouble) xev->event_x; - event->crossing.y = (gdouble) xev->event_y; - event->crossing.x_root = (gdouble) xev->root_x; - event->crossing.y_root = (gdouble) xev->root_y; + event->crossing.x = (gdouble) xev->event_x / scale; + event->crossing.y = (gdouble) xev->event_y / scale; + event->crossing.x_root = (gdouble) xev->root_x / scale; + event->crossing.y_root = (gdouble) xev->root_y / scale; event->crossing.time = xev->time; event->crossing.focus = xev->focus; diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c index 09a4347298..6f56e21ab6 100644 --- a/gdk/x11/gdkdisplay-x11.c +++ b/gdk/x11/gdkdisplay-x11.c @@ -558,11 +558,16 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, { GdkRectangle expose_rect; + int x2, y2; - expose_rect.x = xevent->xexpose.x; - expose_rect.y = xevent->xexpose.y; - expose_rect.width = xevent->xexpose.width; - expose_rect.height = xevent->xexpose.height; + expose_rect.x = xevent->xexpose.x / window_impl->window_scale; + expose_rect.y = xevent->xexpose.y / window_impl->window_scale; + + x2 = (xevent->xexpose.x + xevent->xexpose.width + window_impl->window_scale -1) / window_impl->window_scale; + expose_rect.width = x2 - expose_rect.x; + + y2 = (xevent->xexpose.y + xevent->xexpose.height + window_impl->window_scale -1) / window_impl->window_scale; + expose_rect.height = y2 - expose_rect.y; _gdk_x11_window_process_expose (window, xevent->xexpose.serial, &expose_rect); return_val = FALSE; @@ -573,6 +578,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, case GraphicsExpose: { GdkRectangle expose_rect; + int x2, y2; GDK_NOTE (EVENTS, g_message ("graphics expose:\tdrawable: %ld", @@ -584,10 +590,14 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, break; } - expose_rect.x = xevent->xgraphicsexpose.x; - expose_rect.y = xevent->xgraphicsexpose.y; - expose_rect.width = xevent->xgraphicsexpose.width; - expose_rect.height = xevent->xgraphicsexpose.height; + expose_rect.x = xevent->xgraphicsexpose.x / window_impl->window_scale; + expose_rect.y = xevent->xgraphicsexpose.y / window_impl->window_scale; + + x2 = (xevent->xgraphicsexpose.x + xevent->xgraphicsexpose.width + window_impl->window_scale -1) / window_impl->window_scale; + expose_rect.width = x2 - expose_rect.x; + + y2 = (xevent->xgraphicsexpose.y + xevent->xgraphicsexpose.height + window_impl->window_scale -1) / window_impl->window_scale; + expose_rect.height = y2 - expose_rect.y; _gdk_x11_window_process_expose (window, xevent->xgraphicsexpose.serial, &expose_rect); return_val = FALSE; @@ -773,8 +783,8 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, : "")); if (window && GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT) { - window->width = xevent->xconfigure.width; - window->height = xevent->xconfigure.height; + window->width = xevent->xconfigure.width / window_impl->window_scale; + window->height = xevent->xconfigure.height / window_impl->window_scale; _gdk_window_update_size (window); _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl)); @@ -799,8 +809,8 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, { event->configure.type = GDK_CONFIGURE; event->configure.window = window; - event->configure.width = xevent->xconfigure.width; - event->configure.height = xevent->xconfigure.height; + event->configure.width = xevent->xconfigure.width / window_impl->window_scale; + event->configure.height = xevent->xconfigure.height / window_impl->window_scale; if (!xevent->xconfigure.send_event && !xevent->xconfigure.override_redirect && @@ -818,22 +828,22 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, &tx, &ty, &child_window)) { - event->configure.x = tx; - event->configure.y = ty; + event->configure.x = tx / window_impl->window_scale; + event->configure.y = ty / window_impl->window_scale; } gdk_x11_display_error_trap_pop_ignored (display); } else { - event->configure.x = xevent->xconfigure.x; - event->configure.y = xevent->xconfigure.y; + event->configure.x = xevent->xconfigure.x / window_impl->window_scale; + event->configure.y = xevent->xconfigure.y / window_impl->window_scale; } if (!is_substructure) { window->x = event->configure.x; window->y = event->configure.y; - window->width = xevent->xconfigure.width; - window->height = xevent->xconfigure.height; + window->width = xevent->xconfigure.width / window_impl->window_scale; + window->height = xevent->xconfigure.height / window_impl->window_scale; _gdk_window_update_size (window); _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl)); @@ -1015,11 +1025,15 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator, XDamageNotifyEvent *damage_event = (XDamageNotifyEvent *) xevent; XserverRegion repair; GdkRectangle rect; + int x2, y2; - rect.x = window->x + damage_event->area.x; - rect.y = window->y + damage_event->area.y; - rect.width = damage_event->area.width; - rect.height = damage_event->area.height; + rect.x = window->x + damage_event->area.x / window_impl->window_scale; + rect.y = window->y + damage_event->area.y / window_impl->window_scale; + + x2 = (rect.x * window_impl->window_scale + damage_event->area.width + window_impl->window_scale -1) / window_impl->window_scale; + y2 = (rect.y * window_impl->window_scale + damage_event->area.height + window_impl->window_scale -1) / window_impl->window_scale; + rect.width = x2 - rect.x; + rect.height = y2 - rect.y; repair = XFixesCreateRegion (display_x11->xdisplay, &damage_event->area, 1); diff --git a/gdk/x11/gdkdnd-x11.c b/gdk/x11/gdkdnd-x11.c index b5a6b54acf..3515feaf2f 100644 --- a/gdk/x11/gdkdnd-x11.c +++ b/gdk/x11/gdkdnd-x11.c @@ -510,15 +510,19 @@ gdk_window_cache_new (GdkScreen *screen) { GList *toplevel_windows, *list; GdkWindow *window; + GdkWindowImplX11 *impl; gint x, y, width, height; toplevel_windows = gdk_screen_get_toplevel_windows (screen); for (list = toplevel_windows; list; list = list->next) { window = GDK_WINDOW (list->data); + impl = GDK_WINDOW_IMPL_X11 (window->impl); gdk_window_get_geometry (window, &x, &y, &width, &height); gdk_window_cache_add (result, GDK_WINDOW_XID (window), - x, y, width, height, + x * impl->window_scale, y * impl->window_scale, + width * impl->window_scale, + height * impl->window_scale, gdk_window_is_visible (window)); } g_list_free (toplevel_windows); @@ -556,7 +560,10 @@ gdk_window_cache_new (GdkScreen *screen) if (gdk_screen_is_composited (screen)) { cow = XCompositeGetOverlayWindow (xdisplay, GDK_WINDOW_XID (root_window)); - gdk_window_cache_add (result, cow, 0, 0, gdk_screen_get_width (screen), gdk_screen_get_height (screen), TRUE); + gdk_window_cache_add (result, cow, 0, 0, + gdk_screen_get_width (screen) * GDK_X11_SCREEN(screen)->window_scale, + gdk_screen_get_height (screen) * GDK_X11_SCREEN(screen)->window_scale, + TRUE); XCompositeReleaseOverlayWindow (xdisplay, GDK_WINDOW_XID (root_window)); } #endif @@ -651,12 +658,12 @@ is_pointer_within_shape (GdkDisplay *display, child->shape = NULL; if (gdk_display_supports_shapes (display)) child->shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay, - child->xid, ShapeBounding); + child->xid, 1, ShapeBounding); #ifdef ShapeInput input_shape = NULL; if (gdk_display_supports_input_shapes (display)) input_shape = _gdk_x11_xwindow_get_shape (display_x11->xdisplay, - child->xid, ShapeInput); + child->xid, 1, ShapeInput); if (child->shape && input_shape) { @@ -1744,6 +1751,7 @@ xdnd_position_filter (GdkXEvent *xev, GdkEvent *event, gpointer data) { + GdkWindowImplX11 *impl; XEvent *xevent = (XEvent *)xev; guint32 source_window = xevent->xclient.data.l[0]; gint16 x_root = xevent->xclient.data.l[2] >> 16; @@ -1774,6 +1782,8 @@ xdnd_position_filter (GdkXEvent *xev, (context->protocol == GDK_DRAG_PROTO_XDND) && (GDK_WINDOW_XID (context->source_window) == source_window)) { + impl = GDK_WINDOW_IMPL_X11 (event->any.window->impl); + context_x11 = GDK_X11_DRAG_CONTEXT (context); event->dnd.type = GDK_DRAG_MOTION; @@ -1788,11 +1798,11 @@ xdnd_position_filter (GdkXEvent *xev, if (!context_x11->xdnd_have_actions) context->actions = context->suggested_action; - event->dnd.x_root = x_root; - event->dnd.y_root = y_root; + event->dnd.x_root = x_root / impl->window_scale; + event->dnd.y_root = y_root / impl->window_scale; - context_x11->last_x = x_root; - context_x11->last_y = y_root; + context_x11->last_x = x_root / impl->window_scale; + context_x11->last_y = y_root / impl->window_scale; return GDK_FILTER_TRANSLATE; } @@ -2015,6 +2025,7 @@ gdk_x11_drag_context_find_window (GdkDragContext *context, gint y_root, GdkDragProtocol *protocol) { + GdkX11Screen *screen_x11 = GDK_X11_SCREEN(screen); GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context); GdkWindowCache *window_cache; GdkDisplay *display; @@ -2028,7 +2039,8 @@ gdk_x11_drag_context_find_window (GdkDragContext *context, dest = get_client_window_at_coords (window_cache, drag_window && GDK_WINDOW_IS_X11 (drag_window) ? GDK_WINDOW_XID (drag_window) : None, - x_root, y_root); + x_root * screen_x11->window_scale, + y_root * screen_x11->window_scale); if (context_x11->dest_xid != dest) { @@ -2075,6 +2087,7 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, guint32 time) { GdkX11DragContext *context_x11 = GDK_X11_DRAG_CONTEXT (context); + GdkWindowImplX11 *impl; context_x11->old_actions = context->actions; context->actions = possible_actions; @@ -2198,12 +2211,14 @@ gdk_x11_drag_context_drag_motion (GdkDragContext *context, if (context->dest_window) { + impl = GDK_WINDOW_IMPL_X11 (context->dest_window->impl); + if (context_x11->drag_status == GDK_DRAG_STATUS_DRAG) { switch (context->protocol) { case GDK_DRAG_PROTO_XDND: - xdnd_send_motion (context_x11, x_root, y_root, suggested_action, time); + xdnd_send_motion (context_x11, x_root * impl->window_scale, y_root * impl->window_scale, suggested_action, time); break; case GDK_DRAG_PROTO_ROOTWIN: diff --git a/gdk/x11/gdkgeometry-x11.c b/gdk/x11/gdkgeometry-x11.c index 63620e7874..3f8c8c5f15 100644 --- a/gdk/x11/gdkgeometry-x11.c +++ b/gdk/x11/gdkgeometry-x11.c @@ -42,18 +42,22 @@ _gdk_x11_window_move_resize_child (GdkWindow *window, gint width, gint height) { + GdkWindowImplX11 *impl; + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); - if (width > 65535 || - height > 65535) + 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 > 65535) - width = 65535; - if (height > 65535) - height = 65535; + 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; @@ -69,9 +73,10 @@ _gdk_x11_window_move_resize_child (GdkWindow *window, _gdk_x11_window_tmp_unset_bg (window, TRUE); XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - window->x + window->parent->abs_x, - window->y + window->parent->abs_y, - width, height); + (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); } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 5065f9c5cc..955313bdf4 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -368,6 +368,7 @@ void _gdk_x11_region_get_xrectangles (const cairo_region_t *region, gint x_offset, gint y_offset, + gint scale, XRectangle **rects, gint *n_rects) { @@ -381,10 +382,10 @@ _gdk_x11_region_get_xrectangles (const cairo_region_t *region, for (i = 0; i < n; i++) { cairo_region_get_rectangle (region, i, &box); - rectangles[i].x = CLAMP (box.x + x_offset, G_MINSHORT, G_MAXSHORT); - rectangles[i].y = CLAMP (box.y + y_offset, G_MINSHORT, G_MAXSHORT); - rectangles[i].width = CLAMP (box.width, G_MINSHORT, G_MAXSHORT); - rectangles[i].height = CLAMP (box.height, G_MINSHORT, G_MAXSHORT); + rectangles[i].x = CLAMP ((box.x + x_offset) * scale, G_MINSHORT, G_MAXSHORT); + rectangles[i].y = CLAMP ((box.y + y_offset) * scale, G_MINSHORT, G_MAXSHORT); + rectangles[i].width = CLAMP (box.width * scale, G_MINSHORT, G_MAXSHORT); + rectangles[i].height = CLAMP (box.height * scale, G_MINSHORT, G_MAXSHORT); } *n_rects = n; diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h index defd47e81f..57f7d89d43 100644 --- a/gdk/x11/gdkprivate-x11.h +++ b/gdk/x11/gdkprivate-x11.h @@ -140,11 +140,13 @@ gboolean _gdk_x11_selection_filter_clear_event (XSelectionClearEvent *event); cairo_region_t* _gdk_x11_xwindow_get_shape (Display *xdisplay, Window window, + gint scale, gint shape_type); void _gdk_x11_region_get_xrectangles (const cairo_region_t *region, gint x_offset, gint y_offset, + gint scale, XRectangle **rects, gint *n_rects); diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index 8d3a490bc5..cddb3de853 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -96,13 +96,13 @@ gdk_x11_screen_get_display (GdkScreen *screen) static gint gdk_x11_screen_get_width (GdkScreen *screen) { - return WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen); + return WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen) / GDK_X11_SCREEN (screen)->window_scale; } static gint gdk_x11_screen_get_height (GdkScreen *screen) { - return HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen); + return HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen) / GDK_X11_SCREEN (screen)->window_scale; } static gint @@ -256,7 +256,13 @@ gdk_x11_screen_get_monitor_geometry (GdkScreen *screen, GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); if (dest) - *dest = x11_screen->monitors[monitor_num].geometry; + { + *dest = x11_screen->monitors[monitor_num].geometry; + dest->x /= x11_screen->window_scale; + dest->y /= x11_screen->window_scale; + dest->width /= x11_screen->window_scale; + dest->height /= x11_screen->window_scale; + } } static int @@ -300,6 +306,7 @@ static void get_work_area (GdkScreen *screen, GdkRectangle *area) { + GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); Atom workarea; Atom type; Window win; @@ -321,8 +328,8 @@ get_work_area (GdkScreen *screen, /* Defaults in case of error */ area->x = 0; area->y = 0; - area->width = gdk_screen_get_width (screen); - area->height = gdk_screen_get_height (screen); + area->width = gdk_screen_get_width (screen) / x11_screen->window_scale; + area->height = gdk_screen_get_height (screen) / x11_screen->window_scale; if (!gdk_x11_screen_supports_net_wm_hint (screen, gdk_atom_intern_static_string ("_NET_WORKAREA"))) @@ -359,6 +366,11 @@ get_work_area (GdkScreen *screen, area->width = workareas[desktop * 4 + 2]; area->height = workareas[desktop * 4 + 3]; + area->x /= x11_screen->window_scale; + area->y /= x11_screen->window_scale; + area->width /= x11_screen->window_scale; + area->height /= x11_screen->window_scale; + XFree (ret_workarea); } @@ -385,6 +397,15 @@ gdk_x11_screen_get_monitor_workarea (GdkScreen *screen, } } +static gint +gdk_x11_screen_get_monitor_scale_factor (GdkScreen *screen, + gint monitor_num) +{ + GdkX11Screen *screen_x11 = GDK_X11_SCREEN (screen); + + return screen_x11->window_scale; +} + static GdkVisual * gdk_x11_screen_get_rgba_visual (GdkScreen *screen) { @@ -1032,6 +1053,7 @@ _gdk_x11_screen_new (GdkDisplay *display, GdkScreen *screen; GdkX11Screen *x11_screen; GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); + const char *scale_str; screen = g_object_new (GDK_TYPE_X11_SCREEN, NULL); @@ -1044,7 +1066,21 @@ _gdk_x11_screen_new (GdkDisplay *display, x11_screen->wmspec_check_window = None; /* we want this to be always non-null */ x11_screen->window_manager_name = g_strdup ("unknown"); - + +#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE + scale_str = g_getenv ("GDK_SCALE"); +#else + scale_str = NULL; +#endif + if (scale_str) + { + x11_screen->window_scale = atol (scale_str); + if (x11_screen->window_scale == 0) + x11_screen->window_scale = 1; + } + else + x11_screen->window_scale = 1; + init_multihead (screen); init_randr_support (screen); @@ -1630,6 +1666,7 @@ gdk_x11_screen_class_init (GdkX11ScreenClass *klass) screen_class->get_monitor_plug_name = gdk_x11_screen_get_monitor_plug_name; screen_class->get_monitor_geometry = gdk_x11_screen_get_monitor_geometry; screen_class->get_monitor_workarea = gdk_x11_screen_get_monitor_workarea; + screen_class->get_monitor_scale_factor = gdk_x11_screen_get_monitor_scale_factor; screen_class->get_system_visual = _gdk_x11_screen_get_system_visual; screen_class->get_rgba_visual = gdk_x11_screen_get_rgba_visual; screen_class->is_composited = gdk_x11_screen_is_composited; diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h index 5c88a1a782..7b276578bd 100644 --- a/gdk/x11/gdkscreen-x11.h +++ b/gdk/x11/gdkscreen-x11.h @@ -47,6 +47,8 @@ struct _GdkX11Screen GdkX11Monitor *monitors; gint primary_monitor; + gint window_scale; + /* Xft resources for the display, used for default values for * the Xft/ XSETTINGS */ diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 1f1dbf1161..4141d33d64 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -194,8 +194,8 @@ _gdk_x11_window_update_size (GdkWindowImplX11 *impl) if (impl->cairo_surface) { cairo_xlib_surface_set_size (impl->cairo_surface, - gdk_window_get_width (impl->wrapper), - gdk_window_get_height (impl->wrapper)); + gdk_window_get_width (impl->wrapper) * impl->window_scale, + gdk_window_get_height (impl->wrapper) * impl->window_scale); } } @@ -464,8 +464,11 @@ gdk_x11_ref_cairo_surface (GdkWindow *window) if (!impl->cairo_surface) { impl->cairo_surface = gdk_x11_create_cairo_surface (impl, - gdk_window_get_width (window), - gdk_window_get_height (window)); + gdk_window_get_width (window) * impl->window_scale, + gdk_window_get_height (window) * impl->window_scale); +#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE + cairo_surface_set_device_scale (impl->cairo_surface, impl->window_scale, impl->window_scale); +#endif if (impl->cairo_surface) cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key, @@ -727,6 +730,7 @@ _gdk_x11_screen_init_root_window (GdkScreen *screen) impl->xid = x11_screen->xroot_window; impl->wrapper = window; + impl->window_scale = x11_screen->window_scale; window->window_type = GDK_WINDOW_ROOT; window->depth = DefaultDepthOfScreen (x11_screen->xscreen); @@ -735,8 +739,8 @@ _gdk_x11_screen_init_root_window (GdkScreen *screen) window->y = 0; window->abs_x = 0; window->abs_y = 0; - window->width = WidthOfScreen (x11_screen->xscreen); - window->height = HeightOfScreen (x11_screen->xscreen); + window->width = WidthOfScreen (x11_screen->xscreen) / impl->window_scale; + window->height = HeightOfScreen (x11_screen->xscreen) / impl->window_scale; window->viewable = TRUE; /* see init_randr_support() in gdkscreen-x11.c */ @@ -872,6 +876,7 @@ setup_toplevel_window (GdkWindow *window, GdkWindow *parent) { GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window); + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); GdkDisplay *display = gdk_window_get_display (window); Display *xdisplay = GDK_WINDOW_XDISPLAY (window); XID xid = GDK_WINDOW_XID (window); @@ -900,8 +905,8 @@ setup_toplevel_window (GdkWindow *window, * correct value??? */ size_hints.flags = PSize; - size_hints.width = window->width; - size_hints.height = window->height; + size_hints.width = window->width * impl->window_scale; + size_hints.height = window->height * impl->window_scale; XSetWMNormalHints (xdisplay, xid, &size_hints); @@ -1006,6 +1011,7 @@ _gdk_x11_display_create_window_impl (GdkDisplay *display, impl = g_object_new (GDK_TYPE_WINDOW_IMPL_X11, NULL); window->impl = GDK_WINDOW_IMPL (impl); impl->wrapper = GDK_WINDOW (window); + impl->window_scale = x11_screen->window_scale; xdisplay = x11_screen->xdisplay; @@ -1076,21 +1082,21 @@ _gdk_x11_display_create_window_impl (GdkDisplay *display, class = InputOnly; } - if (window->width > 65535 || - window->height > 65535) + if (window->width * impl->window_scale > 65535 || + window->height * impl->window_scale > 65535) { g_warning ("Native Windows wider or taller than 65535 pixels are not supported"); - if (window->width > 65535) - window->width = 65535; - if (window->height > 65535) - window->height = 65535; + if (window->width * impl->window_scale > 65535) + window->width = 65535 / impl->window_scale; + if (window->height * impl->window_scale > 65535) + window->height = 65535 / impl->window_scale; } impl->xid = XCreateWindow (xdisplay, xparent, - window->x + window->parent->abs_x, - window->y + window->parent->abs_y, - window->width, window->height, + (window->x + window->parent->abs_x) * impl->window_scale, + (window->y + window->parent->abs_y) * impl->window_scale, + window->width * impl->window_scale, window->height * impl->window_scale, 0, window->depth, class, xvisual, xattributes_mask, &xattributes); @@ -1219,6 +1225,7 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display, impl = GDK_WINDOW_IMPL_X11 (win->impl); impl->wrapper = win; + impl->window_scale = GDK_X11_SCREEN (screen)->window_scale; win->parent = gdk_x11_window_lookup_for_display (display, parent); @@ -1231,10 +1238,10 @@ gdk_x11_window_foreign_new_for_display (GdkDisplay *display, impl->xid = window; - win->x = attrs.x; - win->y = attrs.y; - win->width = attrs.width; - win->height = attrs.height; + win->x = attrs.x / impl->window_scale; + win->y = attrs.y / impl->window_scale; + win->width = attrs.width / impl->window_scale; + win->height = attrs.height / impl->window_scale; win->window_type = GDK_WINDOW_FOREIGN; win->destroyed = FALSE; @@ -1765,7 +1772,7 @@ window_x11_move (GdkWindow *window, { XMoveWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - x, y); + x * impl->window_scale, y * impl->window_scale); if (impl->override_redirect) { @@ -1800,7 +1807,7 @@ window_x11_resize (GdkWindow *window, XResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - width, height); + width * impl->window_scale, height * impl->window_scale); if (impl->override_redirect) { @@ -1844,7 +1851,8 @@ window_x11_move_resize (GdkWindow *window, XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), - x, y, width, height); + x * impl->window_scale, y * impl->window_scale, + width * impl->window_scale, height * impl->window_scale); if (impl->override_redirect) { @@ -1898,7 +1906,8 @@ gdk_window_x11_reparent (GdkWindow *window, XReparentWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), GDK_WINDOW_XID (new_parent), - new_parent->abs_x + x, new_parent->abs_y + y); + (new_parent->abs_x + x) * impl->window_scale, + (new_parent->abs_y + y) * impl->window_scale); _gdk_x11_window_tmp_reset_parent_bg (window); _gdk_x11_window_tmp_reset_bg (window, TRUE); @@ -2390,6 +2399,7 @@ gdk_x11_window_set_geometry_hints (GdkWindow *window, const GdkGeometry *geometry, GdkWindowHints geom_mask) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); XSizeHints size_hints; if (GDK_WINDOW_DESTROYED (window) || @@ -2422,31 +2432,37 @@ gdk_x11_window_set_geometry_hints (GdkWindow *window, if (geom_mask & GDK_HINT_MIN_SIZE) { size_hints.flags |= PMinSize; - size_hints.min_width = geometry->min_width; - size_hints.min_height = geometry->min_height; + size_hints.min_width = geometry->min_width * impl->window_scale; + size_hints.min_height = geometry->min_height * impl->window_scale; } if (geom_mask & GDK_HINT_MAX_SIZE) { size_hints.flags |= PMaxSize; - size_hints.max_width = MAX (geometry->max_width, 1); - size_hints.max_height = MAX (geometry->max_height, 1); + size_hints.max_width = MAX (geometry->max_width, 1) * impl->window_scale; + size_hints.max_height = MAX (geometry->max_height, 1) * impl->window_scale; } if (geom_mask & GDK_HINT_BASE_SIZE) { size_hints.flags |= PBaseSize; - size_hints.base_width = geometry->base_width; - size_hints.base_height = geometry->base_height; + size_hints.base_width = geometry->base_width * impl->window_scale; + size_hints.base_height = geometry->base_height * impl->window_scale; } if (geom_mask & GDK_HINT_RESIZE_INC) { size_hints.flags |= PResizeInc; - size_hints.width_inc = geometry->width_inc; - size_hints.height_inc = geometry->height_inc; + size_hints.width_inc = geometry->width_inc * impl->window_scale; + size_hints.height_inc = geometry->height_inc * impl->window_scale; } - + else if (impl->window_scale > 1) + { + size_hints.flags |= PResizeInc; + size_hints.width_inc = impl->window_scale; + size_hints.height_inc = impl->window_scale; + } + if (geom_mask & GDK_HINT_ASPECT) { size_hints.flags |= PAspect; @@ -2491,6 +2507,7 @@ gdk_window_get_geometry_hints (GdkWindow *window, GdkGeometry *geometry, GdkWindowHints *geom_mask) { + GdkWindowImplX11 *impl; XSizeHints *size_hints; glong junk_supplied_mask = 0; @@ -2504,6 +2521,8 @@ gdk_window_get_geometry_hints (GdkWindow *window, !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window)) return; + impl = GDK_WINDOW_IMPL_X11 (window->impl); + size_hints = XAllocSizeHints (); if (!size_hints) return; @@ -2517,22 +2536,22 @@ gdk_window_get_geometry_hints (GdkWindow *window, if (size_hints->flags & PMinSize) { *geom_mask |= GDK_HINT_MIN_SIZE; - geometry->min_width = size_hints->min_width; - geometry->min_height = size_hints->min_height; + geometry->min_width = size_hints->min_width / impl->window_scale; + geometry->min_height = size_hints->min_height / impl->window_scale; } if (size_hints->flags & PMaxSize) { *geom_mask |= GDK_HINT_MAX_SIZE; - geometry->max_width = MAX (size_hints->max_width, 1); - geometry->max_height = MAX (size_hints->max_height, 1); + geometry->max_width = MAX (size_hints->max_width, 1) / impl->window_scale; + geometry->max_height = MAX (size_hints->max_height, 1) / impl->window_scale; } if (size_hints->flags & PResizeInc) { *geom_mask |= GDK_HINT_RESIZE_INC; - geometry->width_inc = size_hints->width_inc; - geometry->height_inc = size_hints->height_inc; + geometry->width_inc = size_hints->width_inc / impl->window_scale; + geometry->height_inc = size_hints->height_inc / impl->window_scale; } if (size_hints->flags & PAspect) @@ -2793,6 +2812,7 @@ static void gdk_window_x11_set_background (GdkWindow *window, cairo_pattern_t *pattern) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); double r, g, b, a; cairo_surface_t *surface; cairo_matrix_t matrix; @@ -2831,12 +2851,17 @@ gdk_window_x11_set_background (GdkWindow *window, cairo_xlib_surface_get_visual (surface) == GDK_VISUAL_XVISUAL (gdk_window_get_visual ((window))) && cairo_xlib_surface_get_display (surface) == GDK_WINDOW_XDISPLAY (window)) { - double x, y; + double x, y, sx, sy; cairo_surface_get_device_offset (surface, &x, &y); + sx = sy = 1.; +#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE + cairo_surface_get_device_scale (surface, &sx, &sy); +#endif /* XXX: This still bombs for non-pixmaps, but there's no way to * detect we're not a pixmap in Cairo... */ - if (x == 0.0 && y == 0.0) + if (x == 0.0 && y == 0.0 && + sx == impl->window_scale && sy == impl->window_scale) { XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), @@ -2900,6 +2925,7 @@ gdk_window_x11_get_geometry (GdkWindow *window, gint *width, gint *height) { + GdkWindowImplX11 *impl; Window root; gint tx; gint ty; @@ -2910,18 +2936,20 @@ gdk_window_x11_get_geometry (GdkWindow *window, if (!GDK_WINDOW_DESTROYED (window)) { + impl = GDK_WINDOW_IMPL_X11 (window->impl); + XGetGeometry (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth); if (x) - *x = tx; + *x = tx / impl->window_scale; if (y) - *y = ty; + *y = ty / impl->window_scale; if (width) - *width = twidth; + *width = twidth / impl->window_scale; if (height) - *height = theight; + *height = theight / impl->window_scale; } } @@ -2932,6 +2960,7 @@ gdk_window_x11_get_root_coords (GdkWindow *window, gint *root_x, gint *root_y) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); gint return_val; Window child; gint tx; @@ -2940,13 +2969,13 @@ gdk_window_x11_get_root_coords (GdkWindow *window, return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), GDK_WINDOW_XROOTWIN (window), - x, y, &tx, &ty, + x * impl->window_scale, y * impl->window_scale, &tx, &ty, &child); if (root_x) - *root_x = tx; + *root_x = tx / impl->window_scale; if (root_y) - *root_y = ty; + *root_y = ty / impl->window_scale; return return_val; } @@ -3001,13 +3030,14 @@ gdk_x11_window_get_frame_extents (GdkWindow *window, while (window->parent && (window->parent)->parent) window = window->parent; - /* Refine our fallback answer a bit using local information */ - rect->x = window->x; - rect->y = window->y; - rect->width = window->width; - rect->height = window->height; - impl = GDK_WINDOW_IMPL_X11 (window->impl); + + /* Refine our fallback answer a bit using local information */ + rect->x = window->x * impl->window_scale; + rect->y = window->y * impl->window_scale; + rect->width = window->width * impl->window_scale; + rect->height = window->height * impl->window_scale; + if (GDK_WINDOW_DESTROYED (window) || impl->override_redirect) return; @@ -3126,6 +3156,10 @@ gdk_x11_window_get_frame_extents (GdkWindow *window, if (vroots) XFree (vroots); + rect->x /= impl->window_scale; + rect->y /= impl->window_scale; + rect->width /= impl->window_scale; + rect->height /= impl->window_scale; gdk_x11_display_error_trap_pop_ignored (display); } @@ -3143,6 +3177,7 @@ gdk_window_x11_get_device_state (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window)) return FALSE; + /*HIDPI: handle coords here?*/ GDK_DEVICE_GET_CLASS (device)->query_state (device, window, NULL, &child, NULL, NULL, @@ -3199,6 +3234,8 @@ do_shape_combine_region (GdkWindow *window, gint offset_y, gint shape) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); + if (GDK_WINDOW_DESTROYED (window)) return; @@ -3237,7 +3274,7 @@ do_shape_combine_region (GdkWindow *window, XRectangle *xrects = NULL; _gdk_x11_region_get_xrectangles (shape_region, - 0, 0, + 0, 0, impl->window_scale, &xrects, &n_rects); if (shape == ShapeBounding) @@ -3248,7 +3285,8 @@ do_shape_combine_region (GdkWindow *window, XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), shape, - offset_x, offset_y, + offset_x * impl->window_scale, + offset_y * impl->window_scale, xrects, n_rects, ShapeSet, YXBanded); @@ -4307,6 +4345,7 @@ gdk_x11_window_set_functions (GdkWindow *window, cairo_region_t * _gdk_x11_xwindow_get_shape (Display *xdisplay, Window window, + gint scale, gint shape_type) { cairo_region_t *shape; @@ -4340,13 +4379,15 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay, return NULL; } + /* NOTE: The scale divisions here may lose some precision if someone + else set the shape to be non-scale precision */ rl = g_new (GdkRectangle, rn); for (i = 0; i < rn; i++) { - rl[i].x = xrl[i].x; - rl[i].y = xrl[i].y; - rl[i].width = xrl[i].width; - rl[i].height = xrl[i].height; + rl[i].x = xrl[i].x / scale; + rl[i].y = xrl[i].y / scale; + rl[i].width = xrl[i].width / scale; + rl[i].height = xrl[i].height / scale; } XFree (xrl); @@ -4360,10 +4401,13 @@ _gdk_x11_xwindow_get_shape (Display *xdisplay, static cairo_region_t * gdk_x11_window_get_shape (GdkWindow *window) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); + if (!GDK_WINDOW_DESTROYED (window) && gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))) return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), + impl->window_scale, ShapeBounding); return NULL; @@ -4373,10 +4417,13 @@ static cairo_region_t * gdk_x11_window_get_input_shape (GdkWindow *window) { #if defined(ShapeInput) + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); + if (!GDK_WINDOW_DESTROYED (window) && gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window))) return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window), + impl->window_scale, ShapeInput); #endif @@ -4467,6 +4514,7 @@ wmspec_send_message (GdkDisplay *display, gint action, gint button) { + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); XClientMessageEvent xclient; memset (&xclient, 0, sizeof (xclient)); @@ -4475,8 +4523,8 @@ wmspec_send_message (GdkDisplay *display, xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE"); xclient.format = 32; - xclient.data.l[0] = root_x; - xclient.data.l[1] = root_y; + xclient.data.l[0] = root_x * impl->window_scale; + xclient.data.l[1] = root_y * impl->window_scale; xclient.data.l[2] = action; xclient.data.l[3] = button; xclient.data.l[4] = 1; /* source indication */ @@ -4798,6 +4846,7 @@ _gdk_x11_moveresize_handle_event (XEvent *event) guint button_mask = 0; GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display); MoveResizeData *mv_resize = get_move_resize_data (display, FALSE); + GdkWindowImplX11 *impl; if (!mv_resize || !mv_resize->moveresize_window) { @@ -4805,6 +4854,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event) return FALSE; } + impl = GDK_WINDOW_IMPL_X11 (mv_resize->moveresize_window->impl); + button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1); switch (event->xany.type) @@ -4824,8 +4875,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event) break; update_pos (mv_resize, - event->xmotion.x_root, - event->xmotion.y_root); + event->xmotion.x_root / impl->window_scale, + event->xmotion.y_root / impl->window_scale); /* This should never be triggered in normal cases, but in the * case where the drag started without an implicit grab being @@ -4839,8 +4890,8 @@ _gdk_x11_moveresize_handle_event (XEvent *event) case ButtonRelease: update_pos (mv_resize, - event->xbutton.x_root, - event->xbutton.y_root); + event->xbutton.x_root / impl->window_scale, + event->xbutton.y_root / impl->window_scale); if (event->xbutton.button == mv_resize->moveresize_button) finish_drag (mv_resize); @@ -4856,14 +4907,14 @@ _gdk_x11_moveresize_handle_event (XEvent *event) switch (ev->evtype) { case XI_Motion: - update_pos (mv_resize, xev->root_x, xev->root_y); + update_pos (mv_resize, xev->root_x / impl->window_scale, xev->root_y / impl->window_scale); state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group); if ((state & button_mask) == 0) finish_drag (mv_resize); break; case XI_ButtonRelease: - update_pos (mv_resize, xev->root_x, xev->root_y); + update_pos (mv_resize, xev->root_x / impl->window_scale, xev->root_y / impl->window_scale); if (xev->detail == mv_resize->moveresize_button) finish_drag (mv_resize); break; @@ -5307,6 +5358,17 @@ gdk_x11_window_get_xid (GdkWindow *window) return GDK_WINDOW_IMPL_X11 (window->impl)->xid; } +static gint +gdk_x11_window_get_scale_factor (GdkWindow *window) +{ + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl); + + if (GDK_WINDOW_DESTROYED (window)) + return 1; + + return impl->window_scale; +} + static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass) { @@ -5394,4 +5456,5 @@ gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass) impl_class->get_property = _gdk_x11_window_get_property; impl_class->change_property = _gdk_x11_window_change_property; impl_class->delete_property = _gdk_x11_window_delete_property; + impl_class->get_scale_factor = gdk_x11_window_get_scale_factor; } diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h index 5079b5d9d6..5a9b31d2b7 100644 --- a/gdk/x11/gdkwindow-x11.h +++ b/gdk/x11/gdkwindow-x11.h @@ -64,6 +64,8 @@ struct _GdkWindowImplX11 Window xid; + gint window_scale; + GdkToplevelX11 *toplevel; /* Toplevel-specific information */ GdkCursor *cursor; GHashTable *device_cursor;