diff --git a/src/compositor/meta-window-actor-x11.c b/src/compositor/meta-window-actor-x11.c index 24d11bab7..5cbd4b80d 100644 --- a/src/compositor/meta-window-actor-x11.c +++ b/src/compositor/meta-window-actor-x11.c @@ -671,14 +671,21 @@ meta_window_actor_x11_process_damage (MetaWindowActorX11 *actor_x11, XDamageNotifyEvent *event) { MetaSurfaceActor *surface; - MtkRectangle area = MTK_RECTANGLE_INIT (event->area.x, - event->area.y, - event->area.width, - event->area.height); surface = meta_window_actor_get_surface (META_WINDOW_ACTOR (actor_x11)); if (surface) - meta_surface_actor_process_damage (surface, &area); + { + MetaWindow *window = + meta_window_actor_get_meta_window (META_WINDOW_ACTOR (actor_x11)); + MtkRectangle area; + + area = MTK_RECTANGLE_INIT (event->area.x, + event->area.y, + event->area.width, + event->area.height); + meta_window_protocol_to_stage_rect (window, &area, &area); + meta_surface_actor_process_damage (surface, &area); + } meta_window_actor_notify_damaged (META_WINDOW_ACTOR (actor_x11)); } diff --git a/src/core/window-private.h b/src/core/window-private.h index 05ef46855..07fb4d68b 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -616,6 +616,18 @@ struct _MetaWindowClass gboolean (*set_transient_for) (MetaWindow *window, MetaWindow *parent); + + void (*stage_to_protocol) (MetaWindow *window, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y); + void (*protocol_to_stage) (MetaWindow *window, + int protocol_x, + int protocol_y, + int *stage_x, + int *stage_y, + MtkRoundingStrategy rounding_strategy); }; /* These differ from window->has_foo_func in that they consider @@ -884,3 +896,16 @@ meta_window_should_attach_to_parent (MetaWindow *window); */ void meta_window_set_normal_hints (MetaWindow *window, MetaSizeHints *hints); + +void meta_window_stage_to_protocol_point (MetaWindow *window, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y); + +void meta_window_protocol_to_stage_point (MetaWindow *window, + int protocol_x, + int protocol_y, + int *stage_x, + int *stage_y, + MtkRoundingStrategy rounding_strategy); diff --git a/src/core/window.c b/src/core/window.c index 86cec773e..b5193e0bf 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -8037,3 +8037,103 @@ meta_window_set_normal_hints (MetaWindow *window, */ } } + +/** + * meta_window_stage_to_protocol_rect: + * @window: A #MetaWindow + * @stage_rect: x #MtkRectangle in stage coordinate space + * @protocol_rect: (out): x #MtkRectangle in protocol coordinate space + * + * Transform the coordinates from stage coordinates to protocol coordinates + */ +void +meta_window_stage_to_protocol_rect (MetaWindow *window, + const MtkRectangle *stage_rect, + MtkRectangle *protocol_rect) +{ + MetaWindowClass *klass = META_WINDOW_GET_CLASS (window); + + klass->stage_to_protocol (window, + stage_rect->x, stage_rect->y, + &protocol_rect->x, &protocol_rect->y); + klass->stage_to_protocol (window, + stage_rect->width, stage_rect->height, + &protocol_rect->width, &protocol_rect->height); +} + +/** + * meta_window_stage_to_protocol_point: + * @window: A #MetaWindow + * @stage_x: x cordinate in stage coordinate space + * @stage_y: y cordinate in stage coordinate space + * @protocol_x: (out): x cordinate in protocol coordinate space + * @protocol_y: (out): y cordinate in protocol coordinate space + * + * Transform the coordinates from stage coordinates to protocol coordinates + */ +void +meta_window_stage_to_protocol_point (MetaWindow *window, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y) +{ + MetaWindowClass *klass = META_WINDOW_GET_CLASS (window); + + klass->stage_to_protocol (window, + stage_x, stage_y, + protocol_x, protocol_y); +} + +/** + * meta_window_protocol_to_stage_rect: + * @window: A #MetaWindow + * @protocol_rect: rectangle in protocol coordinate space + * @stage_rect: (out): rect in stage coordinate space + * + * Transform the coordinates from protocol coordinates to coordinates expected + * by the stage and internal window management logic. + */ +void +meta_window_protocol_to_stage_rect (MetaWindow *window, + const MtkRectangle *protocol_rect, + MtkRectangle *stage_rect) +{ + MetaWindowClass *klass = META_WINDOW_GET_CLASS (window); + + klass->protocol_to_stage (window, + protocol_rect->x, protocol_rect->y, + &stage_rect->x, &stage_rect->y, + MTK_ROUNDING_STRATEGY_SHRINK); + klass->protocol_to_stage (window, + protocol_rect->width, protocol_rect->height, + &stage_rect->width, &stage_rect->height, + MTK_ROUNDING_STRATEGY_GROW); +} + +/** + * meta_window_protocol_to_stage_point: + * @window: A #MetaWindow + * @protocol_x: x cordinate in protocol coordinate space + * @protocol_y: y cordinate in protocol coordinate space + * @stage_x: (out): x cordinate in stage coordinate space + * @stage_y: (out): y cordinate in stage coordinate space + * + * Transform the coordinates from protocol coordinates to coordinates expected + * by the stage and internal window management logic. + */ +void +meta_window_protocol_to_stage_point (MetaWindow *window, + int protocol_x, + int protocol_y, + int *stage_x, + int *stage_y, + MtkRoundingStrategy rounding_strategy) +{ + MetaWindowClass *klass = META_WINDOW_GET_CLASS (window); + + klass->protocol_to_stage (window, + protocol_x, protocol_y, + stage_x, stage_y, + rounding_strategy); +} diff --git a/src/meta/window.h b/src/meta/window.h index 63da5eac7..2af31efab 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -425,3 +425,13 @@ MetaWindowClientType meta_window_get_client_type (MetaWindow *window); META_EXPORT gboolean meta_window_has_pointer (MetaWindow *window); + +META_EXPORT +void meta_window_stage_to_protocol_rect (MetaWindow *window, + const MtkRectangle *stage_rect, + MtkRectangle *protocol_rect); + +META_EXPORT +void meta_window_protocol_to_stage_rect (MetaWindow *window, + const MtkRectangle *protocol_rect, + MtkRectangle *stage_rect); diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c index 37b34066f..83ad04355 100644 --- a/src/wayland/meta-wayland-cursor-surface.c +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -101,24 +101,20 @@ cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite, logical_monitor = meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y); - - if (!meta_wayland_surface_is_xwayland (surface)) + if (logical_monitor) { - if (logical_monitor) - { - int surface_scale = surface->applied_state.scale; - float texture_scale; + int surface_scale = surface->applied_state.scale; + float texture_scale; - if (meta_backend_is_stage_views_scaled (backend)) - texture_scale = 1.0f / surface_scale; - else - texture_scale = (meta_logical_monitor_get_scale (logical_monitor) / - surface_scale); + if (meta_backend_is_stage_views_scaled (backend)) + texture_scale = 1.0f / surface_scale; + else + texture_scale = (meta_logical_monitor_get_scale (logical_monitor) / + surface_scale); - meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale); - meta_cursor_sprite_set_texture_transform (cursor_sprite, - surface->buffer_transform); - } + meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale); + meta_cursor_sprite_set_texture_transform (cursor_sprite, + surface->buffer_transform); } meta_wayland_surface_set_main_monitor (surface, logical_monitor); diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c index e062d25cc..c8dfd6873 100644 --- a/src/wayland/meta-wayland-outputs.c +++ b/src/wayland/meta-wayland-outputs.c @@ -31,6 +31,10 @@ #include "backends/meta-monitor-manager-private.h" #include "wayland/meta-wayland-private.h" +#ifdef HAVE_XWAYLAND +#include "wayland/meta-xwayland.h" +#endif + #include "xdg-output-unstable-v1-server-protocol.h" /* Wayland protocol headers list new additions, not deprecations */ @@ -50,6 +54,8 @@ struct _MetaWaylandOutput { GObject parent; + MetaWaylandCompositor *compositor; + struct wl_global *global; GList *resources; GList *xdg_output_resources; @@ -157,6 +163,37 @@ wl_output_transform_from_transform (MtkMonitorTransform transform) g_assert_not_reached (); } +#ifdef HAVE_XWAYLAND +static gboolean +is_xwayland_resource (MetaWaylandOutput *wayland_output, + struct wl_resource *resource) +{ + MetaXWaylandManager *manager = &wayland_output->compositor->xwayland_manager; + + return resource && wl_resource_get_client (resource) == manager->client; +} +#endif + +static void +maybe_scale_for_xwayland (MetaWaylandOutput *wayland_output, + struct wl_resource *resource, + int *x, + int *y) +{ +#ifdef HAVE_XWAYLAND + if (is_xwayland_resource (wayland_output, resource)) + { + MetaXWaylandManager *xwayland_manager = + &wayland_output->compositor->xwayland_manager; + int xwayland_scale; + + xwayland_scale = meta_xwayland_get_effective_scale (xwayland_manager); + *x *= xwayland_scale; + *y *= xwayland_scale; + } +#endif +} + static void send_output_events (struct wl_resource *resource, MetaWaylandOutput *wayland_output, @@ -242,6 +279,9 @@ send_output_events (struct wl_resource *resource, wl_transform = wl_output_transform_from_transform (transform); + maybe_scale_for_xwayland (wayland_output, resource, + &layout.x, + &layout.y); wl_output_send_geometry (resource, layout.x, layout.y, @@ -424,6 +464,7 @@ meta_wayland_output_new (MetaWaylandCompositor *compositor, MetaWaylandOutput *wayland_output; wayland_output = g_object_new (META_TYPE_WAYLAND_OUTPUT, NULL); + wayland_output->compositor = compositor; wayland_output->global = wl_global_create (compositor->wayland_display, &wl_output_interface, META_WL_OUTPUT_VERSION, @@ -618,6 +659,7 @@ send_xdg_output_events (struct wl_resource *resource, if (need_all_events || old_layout.x != layout.x || old_layout.y != layout.y) { + maybe_scale_for_xwayland (wayland_output, resource, &layout.x, &layout.y); zxdg_output_v1_send_logical_position (resource, layout.x, layout.y); need_done = TRUE; } @@ -625,6 +667,7 @@ send_xdg_output_events (struct wl_resource *resource, if (need_all_events || old_layout.width != layout.width || old_layout.height != layout.height) { + maybe_scale_for_xwayland (wayland_output, resource, &layout.width, &layout.height); zxdg_output_v1_send_logical_size (resource, layout.width, layout.height); need_done = TRUE; } @@ -747,7 +790,7 @@ meta_wayland_outputs_init (MetaWaylandCompositor *compositor) MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); - g_signal_connect (monitor_manager, "monitors-changed-internal", + g_signal_connect (monitor_manager, "monitors-changed", G_CALLBACK (on_monitors_changed), compositor); compositor->outputs = diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 5f6697fa5..9deb267e4 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -1250,6 +1250,20 @@ pointer_set_cursor (struct wl_client *client, cursor_surface = META_WAYLAND_CURSOR_SURFACE (surface->role); meta_wayland_cursor_surface_set_renderer (cursor_surface, cursor_renderer); + +#ifdef HAVE_XWAYLAND + if (meta_wayland_surface_is_xwayland (surface)) + { + MetaXWaylandManager *xwayland_manager = + &surface->compositor->xwayland_manager; + int scale; + + scale = meta_xwayland_get_effective_scale (xwayland_manager); + hot_x = (int32_t) round (hot_x / (double) scale); + hot_y = (int32_t) round (hot_y / (double) scale); + } +#endif + meta_wayland_cursor_surface_set_hotspot (cursor_surface, hot_x, hot_y); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index fa335b030..d45fc00a8 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -800,9 +800,6 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface, state->buffer->type != META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL)); } - if (state->scale > 0) - surface->applied_state.scale = state->scale; - if (state->has_new_buffer_transform) surface->buffer_transform = state->buffer_transform; @@ -822,6 +819,28 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface, surface->viewport.has_dst_size = surface->viewport.dst_width > 0; } + if (meta_wayland_surface_is_xwayland (surface)) + { +#ifdef HAVE_XWAYLAND + MetaXWaylandManager *xwayland_manager = + &surface->compositor->xwayland_manager; + + if (surface->viewport.has_dst_size) + { + surface->applied_state.scale = 1; + } + else + { + surface->applied_state.scale = + meta_xwayland_get_effective_scale (xwayland_manager); + } +#endif + } + else if (state->scale > 0) + { + surface->applied_state.scale = state->scale; + } + state->derived.surface_size_changed = meta_wayland_surface_get_width (surface) != old_width || meta_wayland_surface_get_height (surface) != old_height; @@ -999,8 +1018,9 @@ meta_wayland_surface_commit (MetaWaylandSurface *surface) MetaMultiTexture *committed_texture = surface->committed_state.texture; int committed_scale = surface->committed_state.scale; - if ((meta_multi_texture_get_width (committed_texture) % committed_scale != 0) || - (meta_multi_texture_get_height (committed_texture) % committed_scale != 0)) + if (((meta_multi_texture_get_width (committed_texture) % committed_scale != 0) || + (meta_multi_texture_get_height (committed_texture) % committed_scale != 0)) && + !meta_wayland_surface_is_xwayland (surface)) { if (surface->role && !META_IS_WAYLAND_CURSOR_SURFACE (surface->role)) { @@ -1530,6 +1550,16 @@ meta_wayland_surface_update_outputs (MetaWaylandSurface *surface) g_hash_table_foreach (surface->compositor->outputs, update_surface_output_state, surface); + + if (meta_wayland_surface_is_xwayland (surface)) + { +#ifdef HAVE_XWAYLAND + MetaXWaylandManager *xwayland_manager = + &surface->compositor->xwayland_manager; + + surface->applied_state.scale = meta_xwayland_get_effective_scale (xwayland_manager); +#endif + } } void diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index 779effa67..c3d0f4854 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -820,6 +820,33 @@ meta_window_wayland_set_transient_for (MetaWindow *window, return TRUE; } +static void +meta_window_wayland_stage_to_protocol (MetaWindow *window, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y) +{ + if (protocol_x) + *protocol_x = stage_x; + if (protocol_y) + *protocol_y = stage_y; +} + +static void +meta_window_wayland_protocol_to_stage (MetaWindow *window, + int protocol_x, + int protocol_y, + int *stage_x, + int *stage_y, + MtkRoundingStrategy rounding_strategy) +{ + if (stage_x) + *stage_x = protocol_x; + if (stage_y) + *stage_y = protocol_y; +} + static MetaStackLayer meta_window_wayland_calculate_layer (MetaWindow *window) { @@ -938,6 +965,8 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->is_focus_async = meta_window_wayland_is_focus_async; window_class->get_wayland_surface = meta_window_wayland_get_wayland_surface; window_class->set_transient_for = meta_window_wayland_set_transient_for; + window_class->stage_to_protocol = meta_window_wayland_stage_to_protocol; + window_class->protocol_to_stage = meta_window_wayland_protocol_to_stage; obj_props[PROP_SURFACE] = g_param_spec_object ("surface", NULL, NULL, diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c index 2a1390ef4..5eeb98ed9 100644 --- a/src/wayland/meta-window-xwayland.c +++ b/src/wayland/meta-window-xwayland.c @@ -27,8 +27,9 @@ #include "x11/window-x11-private.h" #include "x11/xprops.h" #include "wayland/meta-window-xwayland.h" -#include "wayland/meta-wayland.h" +#include "wayland/meta-wayland-private.h" #include "wayland/meta-wayland-surface-private.h" +#include "wayland/meta-xwayland.h" enum { @@ -315,6 +316,69 @@ meta_window_xwayland_process_property_notify (MetaWindow *window, meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } +static void +meta_window_xwayland_stage_to_protocol (MetaWindow *window, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y) +{ + MetaDisplay *display = meta_window_get_display (window); + MetaContext *context = meta_display_get_context (display); + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; + int scale; + + scale = meta_xwayland_get_effective_scale (xwayland_manager); + if (protocol_x) + *protocol_x = stage_x * scale; + if (protocol_y) + *protocol_y = stage_y * scale; +} + +static void +meta_window_xwayland_protocol_to_stage (MetaWindow *window, + int protocol_x, + int protocol_y, + int *stage_x, + int *stage_y, + MtkRoundingStrategy rounding_strategy) +{ + MetaDisplay *display = meta_window_get_display (window); + MetaContext *context = meta_display_get_context (display); + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = &wayland_compositor->xwayland_manager; + int xwayland_scale; + float scale; + + xwayland_scale = meta_xwayland_get_effective_scale (xwayland_manager); + scale = 1.0f / xwayland_scale; + + switch (rounding_strategy) + { + case MTK_ROUNDING_STRATEGY_SHRINK: + if (stage_x) + *stage_x = (int) floorf (protocol_x * scale); + if (stage_y) + *stage_y = (int) floorf (protocol_y * scale); + break; + case MTK_ROUNDING_STRATEGY_GROW: + if (stage_x) + *stage_x = (int) ceilf (protocol_x * scale); + if (stage_y) + *stage_y = (int) ceilf (protocol_y * scale); + break; + case MTK_ROUNDING_STRATEGY_ROUND: + if (stage_x) + *stage_x = (int) roundf (protocol_x * scale); + if (stage_y) + *stage_y = (int) roundf (protocol_y * scale); + break; + } +} + static void meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) { @@ -326,6 +390,8 @@ meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts; window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited; window_class->get_wayland_surface = meta_window_xwayland_get_wayland_surface; + window_class->stage_to_protocol = meta_window_xwayland_stage_to_protocol; + window_class->protocol_to_stage = meta_window_xwayland_protocol_to_stage; window_x11_class->freeze_commits = meta_window_xwayland_freeze_commits; window_x11_class->thaw_commits = meta_window_xwayland_thaw_commits; diff --git a/src/wayland/meta-xwayland-private.h b/src/wayland/meta-xwayland-private.h index 7a9cb73fd..9e06f0315 100644 --- a/src/wayland/meta-xwayland-private.h +++ b/src/wayland/meta-xwayland-private.h @@ -20,6 +20,7 @@ #include #include "wayland/meta-wayland-private.h" +#include "wayland/meta-xwayland.h" gboolean meta_xwayland_init (MetaXWaylandManager *manager, diff --git a/src/wayland/meta-xwayland-surface.c b/src/wayland/meta-xwayland-surface.c index 8fa1c72a9..c6daf9b26 100644 --- a/src/wayland/meta-xwayland-surface.c +++ b/src/wayland/meta-xwayland-surface.c @@ -163,13 +163,19 @@ meta_xwayland_surface_get_relative_coordinates (MetaWaylandSurfaceRole *surface_ float *out_sy) { MetaXwaylandSurface *xwayland_surface = META_XWAYLAND_SURFACE (surface_role); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandCompositor *compositor = + meta_wayland_surface_get_compositor (surface); MtkRectangle window_rect = { 0 }; + int xwayland_scale; if (xwayland_surface->window) meta_window_get_buffer_rect (xwayland_surface->window, &window_rect); - *out_sx = abs_x - window_rect.x; - *out_sy = abs_y - window_rect.y; + xwayland_scale = meta_xwayland_get_effective_scale (&compositor->xwayland_manager); + *out_sx = (abs_x - window_rect.x) * xwayland_scale; + *out_sy = (abs_y - window_rect.y) * xwayland_scale; } static MetaWaylandSurface * diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 8b8519d0c..962dfaea5 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -131,6 +131,42 @@ backend_from_x11_display (MetaX11Display *x11_display) return meta_context_get_backend (context); } +static void +stage_to_protocol (MetaX11Display *x11_display, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y) +{ + MetaDisplay *display = meta_x11_display_get_display (x11_display); + MetaContext *context = meta_display_get_context (display); + int scale = 1; + + switch (meta_context_get_compositor_type (context)) + { + case META_COMPOSITOR_TYPE_WAYLAND: + { +#ifdef HAVE_XWAYLAND + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = + &wayland_compositor->xwayland_manager; + + scale = meta_xwayland_get_effective_scale (xwayland_manager); +#endif + break; + } + + case META_COMPOSITOR_TYPE_X11: + break; + } + + if (protocol_x) + *protocol_x = stage_x * scale; + if (protocol_y) + *protocol_y = stage_y * scale; +} + static void meta_x11_display_unmanage_windows (MetaX11Display *x11_display) { @@ -181,10 +217,32 @@ update_ui_scaling_factor (MetaX11Display *x11_display) MetaX11DisplayPrivate *priv = meta_x11_display_get_instance_private (x11_display); MetaBackend *backend = backend_from_x11_display (x11_display); - MetaSettings *settings = meta_backend_get_settings (backend); - int ui_scaling_factor; + MetaContext *context = meta_backend_get_context (backend); + int ui_scaling_factor = 1; + + switch (meta_context_get_compositor_type (context)) + { + case META_COMPOSITOR_TYPE_WAYLAND: + { +#ifdef HAVE_XWAYLAND + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = + &wayland_compositor->xwayland_manager; + + ui_scaling_factor = meta_xwayland_get_effective_scale (xwayland_manager); +#endif + break; + } + case META_COMPOSITOR_TYPE_X11: + { + MetaSettings *settings = meta_backend_get_settings (backend); + + ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); + break; + } + } - ui_scaling_factor = meta_settings_get_ui_scaling_factor (settings); meta_dbus_x11_set_ui_scaling_factor (priv->dbus_api, ui_scaling_factor); } @@ -638,6 +696,9 @@ set_desktop_geometry_hint (MetaX11Display *x11_display) return; meta_display_get_size (x11_display->display, &monitor_width, &monitor_height); + stage_to_protocol (x11_display, + monitor_width, monitor_height, + &monitor_width, &monitor_height); data[0] = monitor_width; data[1] = monitor_height; @@ -1047,14 +1108,22 @@ set_workspace_work_area_hint (MetaWorkspace *workspace, for (l = logical_monitors; l; l = l->next) { - MtkRectangle area; + MtkRectangle stage_area; + MtkRectangle protocol_area; - meta_workspace_get_work_area_for_logical_monitor (workspace, l->data, &area); + meta_workspace_get_work_area_for_logical_monitor (workspace, l->data, + &stage_area); - tmp[0] = area.x; - tmp[1] = area.y; - tmp[2] = area.width; - tmp[3] = area.height; + stage_to_protocol (x11_display, + stage_area.x, stage_area.y, + &protocol_area.x, &protocol_area.y); + stage_to_protocol (x11_display, + stage_area.width, stage_area.height, + &protocol_area.width, &protocol_area.height); + tmp[0] = protocol_area.x; + tmp[1] = protocol_area.y; + tmp[2] = protocol_area.width; + tmp[3] = protocol_area.height; tmp += 4; } @@ -1083,7 +1152,6 @@ set_work_area_hint (MetaDisplay *display, int num_workspaces; GList *l; unsigned long *data, *tmp; - MtkRectangle area; num_workspaces = meta_workspace_manager_get_n_workspaces (workspace_manager); data = g_new (unsigned long, num_workspaces * 4); @@ -1092,14 +1160,22 @@ set_work_area_hint (MetaDisplay *display, for (l = workspace_manager->workspaces; l; l = l->next) { MetaWorkspace *workspace = l->data; + MtkRectangle stage_area; + MtkRectangle protocol_area; - meta_workspace_get_work_area_all_monitors (workspace, &area); + meta_workspace_get_work_area_all_monitors (workspace, &stage_area); set_workspace_work_area_hint (workspace, x11_display); - tmp[0] = area.x; - tmp[1] = area.y; - tmp[2] = area.width; - tmp[3] = area.height; + stage_to_protocol (x11_display, + stage_area.x, stage_area.y, + &protocol_area.x, &protocol_area.y); + stage_to_protocol (x11_display, + stage_area.width, stage_area.height, + &protocol_area.width, &protocol_area.height); + tmp[0] = protocol_area.x; + tmp[1] = protocol_area.y; + tmp[2] = protocol_area.width; + tmp[3] = protocol_area.height; tmp += 4; } @@ -1279,6 +1355,41 @@ initialize_dbus_interface (MetaX11Display *x11_display) update_ui_scaling_factor (x11_display); } +static void +experimental_features_changed (MetaSettings *settings, + MetaExperimentalFeature old_experimental_features, + MetaX11Display *x11_display) +{ + gboolean was_xwayland_native_scaling; + gboolean was_stage_views_scaled; + gboolean is_xwayland_native_scaling; + gboolean is_stage_views_scaled; + + was_xwayland_native_scaling = + !!(old_experimental_features & + META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING); + was_stage_views_scaled = + !!(old_experimental_features & + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); + + is_xwayland_native_scaling = + meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_XWAYLAND_NATIVE_SCALING); + is_stage_views_scaled = + meta_settings_is_experimental_feature_enabled ( + settings, + META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER); + + if (is_xwayland_native_scaling != was_xwayland_native_scaling || + is_stage_views_scaled != was_stage_views_scaled) + { + update_ui_scaling_factor (x11_display); + set_desktop_geometry_hint (x11_display); + set_work_area_hint (x11_display->display, x11_display); + } +} + /** * meta_x11_display_new: * @@ -1297,6 +1408,7 @@ meta_x11_display_new (MetaDisplay *display, MetaBackend *backend = meta_context_get_backend (context); MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (backend); + MetaSettings *settings = meta_backend_get_settings (backend); g_autoptr (MetaX11Display) x11_display = NULL; Display *xdisplay; Screen *xscreen; @@ -1469,7 +1581,7 @@ meta_x11_display_new (MetaDisplay *display, "monitors-changed-internal", G_CALLBACK (on_monitors_changed_internal), x11_display, - 0); + G_CONNECT_AFTER); init_leader_window (x11_display, ×tamp); x11_display->timestamp = timestamp; @@ -1562,6 +1674,11 @@ meta_x11_display_new (MetaDisplay *display, meta_prefs_add_listener (prefs_changed_callback, x11_display); + g_signal_connect_object (settings, + "experimental-features-changed", + G_CALLBACK (experimental_features_changed), + x11_display, 0); + set_work_area_hint (display, x11_display); g_signal_connect_object (display, "workareas-changed", @@ -1775,16 +1892,12 @@ meta_x11_display_reload_cursor (MetaX11Display *x11_display) } static void -set_cursor_theme (Display *xdisplay, - MetaBackend *backend) +set_cursor_theme (Display *xdisplay, + const char *theme, + int size) { - MetaSettings *settings = meta_backend_get_settings (backend); - int scale; - - scale = meta_settings_get_ui_scaling_factor (settings); - XcursorSetTheme (xdisplay, meta_prefs_get_cursor_theme ()); - XcursorSetDefaultSize (xdisplay, - meta_prefs_get_cursor_size () * scale); + XcursorSetTheme (xdisplay, theme); + XcursorSetDefaultSize (xdisplay, size); } static void @@ -1836,8 +1949,37 @@ static void update_cursor_theme (MetaX11Display *x11_display) { MetaBackend *backend = backend_from_x11_display (x11_display); + MetaContext *context = meta_backend_get_context (backend); + MetaSettings *settings = meta_backend_get_settings (backend); + int scale = 1; + int size; + const char *theme; - set_cursor_theme (x11_display->xdisplay, backend); + switch (meta_context_get_compositor_type (context)) + { + case META_COMPOSITOR_TYPE_WAYLAND: + { +#ifdef HAVE_XWAYLAND + MetaWaylandCompositor *wayland_compositor = + meta_context_get_wayland_compositor (context); + MetaXWaylandManager *xwayland_manager = + &wayland_compositor->xwayland_manager; + + scale = meta_xwayland_get_effective_scale (xwayland_manager); +#endif + break; + } + + case META_COMPOSITOR_TYPE_X11: + scale = meta_settings_get_ui_scaling_factor (settings); + break; + } + + size = meta_prefs_get_cursor_size () * scale; + + theme = meta_prefs_get_cursor_theme (); + + set_cursor_theme (x11_display->xdisplay, theme, size); schedule_reload_x11_cursor (x11_display); #ifdef HAVE_X11 @@ -1846,7 +1988,7 @@ update_cursor_theme (MetaX11Display *x11_display) MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend); Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11); - set_cursor_theme (xdisplay, backend); + set_cursor_theme (xdisplay, theme, size); meta_backend_x11_reload_cursor (backend_x11); } #endif diff --git a/src/x11/meta-x11-frame.c b/src/x11/meta-x11-frame.c index 29f72438f..9030a9256 100644 --- a/src/x11/meta-x11-frame.c +++ b/src/x11/meta-x11-frame.c @@ -78,6 +78,7 @@ meta_window_x11_set_frame_xwindow (MetaWindow *window, g_autoptr (MetaFrame) frame = NULL; MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11Private *priv = meta_window_x11_get_private (window_x11); + int child_x, child_y; if (priv->frame) return; @@ -136,12 +137,17 @@ meta_window_x11_set_frame_xwindow (MetaWindow *window, meta_stack_tracker_record_remove (window->display->stack_tracker, meta_window_x11_get_xwindow (window), XNextRequest (x11_display->xdisplay)); + meta_window_stage_to_protocol_point (window, + frame->child_x, + frame->child_y, + &child_x, + &child_y); XReparentWindow (x11_display->xdisplay, meta_window_x11_get_xwindow (window), frame->xwindow, - frame->child_x, - frame->child_y); + child_x, + child_y); if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay)) { @@ -239,6 +245,8 @@ meta_window_destroy_frame (MetaWindow *window) if (!x11_display->closing) { + int child_x, child_y; + if (!window->unmanaging) { meta_stack_tracker_record_add (window->display->stack_tracker, @@ -246,6 +254,12 @@ meta_window_destroy_frame (MetaWindow *window) XNextRequest (x11_display->xdisplay)); } + meta_window_stage_to_protocol_point (window, + frame->rect.x + borders.invisible.left, + frame->rect.y + borders.invisible.top, + &child_x, + &child_y); + XReparentWindow (x11_display->xdisplay, meta_window_x11_get_xwindow (window), x11_display->xroot, @@ -253,8 +267,7 @@ meta_window_destroy_frame (MetaWindow *window) * coordinates here means we'll need to ensure a configure * notify event is sent; see bug 399552. */ - frame->rect.x + borders.invisible.left, - frame->rect.y + borders.invisible.top); + child_x, child_y); window->reparents_pending += 1; } @@ -323,12 +336,25 @@ meta_frame_query_borders (MetaFrame *frame, if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) == Success && res == Success && nitems == 4) { - borders->invisible = (MetaFrameBorder) { - ((long *) data)[0], - ((long *) data)[1], - ((long *) data)[2], - ((long *) data)[3], - }; + int left, right, top, bottom; + + meta_window_protocol_to_stage_point (window, + ((long *) data)[0], + ((long *) data)[1], + &left, + &right, + MTK_ROUNDING_STRATEGY_GROW); + meta_window_protocol_to_stage_point (window, + ((long *) data)[2], + ((long *) data)[3], + &top, + &bottom, + MTK_ROUNDING_STRATEGY_GROW); + + borders->invisible.left = left; + borders->invisible.right = right; + borders->invisible.top = top; + borders->invisible.bottom = bottom; } else { @@ -351,12 +377,24 @@ meta_frame_query_borders (MetaFrame *frame, if (mtk_x11_error_trap_pop_with_return (x11_display->xdisplay) == Success && res == Success && nitems == 4) { - borders->visible = (MetaFrameBorder) { - ((long *) data)[0], - ((long *) data)[1], - ((long *) data)[2], - ((long *) data)[3], - }; + int left, right, top, bottom; + + meta_window_protocol_to_stage_point (window, + ((long *) data)[0], + ((long *) data)[1], + &left, + &right, + MTK_ROUNDING_STRATEGY_GROW); + meta_window_protocol_to_stage_point (window, + ((long *) data)[2], + ((long *) data)[3], + &top, + &bottom, + MTK_ROUNDING_STRATEGY_GROW); + borders->visible.left = left; + borders->visible.right = right; + borders->visible.top = top; + borders->visible.bottom = bottom; } else { @@ -405,6 +443,7 @@ meta_frame_sync_to_window (MetaFrame *frame, { MetaWindow *window = frame->window; MetaX11Display *x11_display = window->display->x11_display; + MtkRectangle rect; meta_topic (META_DEBUG_GEOMETRY, "Syncing frame geometry %d,%d %dx%d (SE: %d,%d)", @@ -415,12 +454,14 @@ meta_frame_sync_to_window (MetaFrame *frame, mtk_x11_error_trap_push (x11_display->xdisplay); + meta_window_stage_to_protocol_rect (window, &frame->rect, &rect); + XMoveResizeWindow (x11_display->xdisplay, frame->xwindow, - frame->rect.x, - frame->rect.y, - frame->rect.width, - frame->rect.height); + rect.x, + rect.y, + rect.width, + rect.height); mtk_x11_error_trap_pop (x11_display->xdisplay); @@ -458,6 +499,7 @@ send_configure_notify (MetaFrame *frame) { MetaX11Display *x11_display = frame->window->display->x11_display; XEvent event = { 0 }; + MtkRectangle configure_rect; /* We never get told by the frames client, just reassert the * current frame size. @@ -466,10 +508,15 @@ send_configure_notify (MetaFrame *frame) event.xconfigure.display = x11_display->xdisplay; event.xconfigure.event = frame->xwindow; event.xconfigure.window = frame->xwindow; - event.xconfigure.x = frame->rect.x; - event.xconfigure.y = frame->rect.y; - event.xconfigure.width = frame->rect.width; - event.xconfigure.height = frame->rect.height; + + meta_window_stage_to_protocol_rect (frame->window, + &frame->rect, + &configure_rect); + + event.xconfigure.x = configure_rect.x; + event.xconfigure.y = configure_rect.y; + event.xconfigure.width = configure_rect.width; + event.xconfigure.height = configure_rect.height; event.xconfigure.border_width = 0; event.xconfigure.above = None; event.xconfigure.override_redirect = False; diff --git a/src/x11/window-props.c b/src/x11/window-props.c index c12de92d2..9ee56de71 100644 --- a/src/x11/window-props.c +++ b/src/x11/window-props.c @@ -305,10 +305,11 @@ reload_icon_geometry (MetaWindow *window, { MtkRectangle geometry; - geometry.x = (int)value->v.cardinal_list.cardinals[0]; - geometry.y = (int)value->v.cardinal_list.cardinals[1]; - geometry.width = (int)value->v.cardinal_list.cardinals[2]; - geometry.height = (int)value->v.cardinal_list.cardinals[3]; + geometry = MTK_RECTANGLE_INIT (value->v.cardinal_list.cardinals[0], + value->v.cardinal_list.cardinals[1], + value->v.cardinal_list.cardinals[2], + value->v.cardinal_list.cardinals[3]); + meta_window_protocol_to_stage_rect (window, &geometry, &geometry); meta_window_set_icon_geometry (window, &geometry); } @@ -373,11 +374,27 @@ reload_gtk_frame_extents (MetaWindow *window, } else { + int left, right, top, bottom; MetaFrameBorder extents; - extents.left = (int)value->v.cardinal_list.cardinals[0]; - extents.right = (int)value->v.cardinal_list.cardinals[1]; - extents.top = (int)value->v.cardinal_list.cardinals[2]; - extents.bottom = (int)value->v.cardinal_list.cardinals[3]; + + meta_window_protocol_to_stage_point (window, + value->v.cardinal_list.cardinals[0], + value->v.cardinal_list.cardinals[1], + &left, + &right, + MTK_ROUNDING_STRATEGY_GROW); + meta_window_protocol_to_stage_point (window, + value->v.cardinal_list.cardinals[2], + value->v.cardinal_list.cardinals[3], + &top, + &bottom, + MTK_ROUNDING_STRATEGY_GROW); + + extents.left = left; + extents.right = right; + extents.top = top; + extents.bottom = bottom; + meta_window_set_custom_frame_extents (window, &extents, initial); } } @@ -680,13 +697,15 @@ reload_opaque_region (MetaWindow *window, i = 0; while (i < nitems) { + MtkRectangle region_rect = MTK_RECTANGLE_INIT (region[i + 0], + region[i + 1], + region[i + 2], + region[i + 3]); MtkRectangle *rect = &rects[rect_index]; - rect->x = region[i++]; - rect->y = region[i++]; - rect->width = region[i++]; - rect->height = region[i++]; + meta_window_protocol_to_stage_rect (window, ®ion_rect, rect); + i += 4; rect_index++; } @@ -1219,6 +1238,50 @@ hints_have_changed (const MetaSizeHints *old, FLAG_TOGGLED_OFF (old, new, META_SIZE_HINTS_PROGRAM_WIN_GRAVITY); } +static void +scale_size_hints (MetaWindow *window, + MetaSizeHints *hints) +{ + meta_window_protocol_to_stage_point (window, + hints->x, hints->y, + &hints->x, &hints->y, + MTK_ROUNDING_STRATEGY_SHRINK); + meta_window_protocol_to_stage_point (window, + hints->width, hints->height, + &hints->width, &hints->height, + MTK_ROUNDING_STRATEGY_GROW); + + meta_window_protocol_to_stage_point (window, + hints->min_width, hints->min_height, + &hints->min_width, &hints->min_height, + MTK_ROUNDING_STRATEGY_GROW); + + meta_window_protocol_to_stage_point (window, + hints->max_width, hints->max_height, + &hints->max_width, &hints->max_height, + MTK_ROUNDING_STRATEGY_GROW); + + meta_window_protocol_to_stage_point (window, + hints->width_inc, hints->height_inc, + &hints->width_inc, &hints->height_inc, + MTK_ROUNDING_STRATEGY_ROUND); + + meta_window_protocol_to_stage_point (window, + hints->min_aspect.x, hints->min_aspect.y, + &hints->min_aspect.x, &hints->min_aspect.y, + MTK_ROUNDING_STRATEGY_ROUND); + + meta_window_protocol_to_stage_point (window, + hints->max_aspect.x, hints->max_aspect.y, + &hints->max_aspect.x, &hints->max_aspect.y, + MTK_ROUNDING_STRATEGY_ROUND); + + meta_window_protocol_to_stage_point (window, + hints->base_width, hints->base_height, + &hints->base_width, &hints->base_height, + MTK_ROUNDING_STRATEGY_GROW); +} + static void reload_normal_hints (MetaWindow *window, MetaPropValue *value, @@ -1233,8 +1296,18 @@ reload_normal_hints (MetaWindow *window, old_hints = window->size_hints; - meta_window_set_normal_hints (window, - (MetaSizeHints*)value->v.size_hints.hints); + if (value->v.size_hints.hints) + { + MetaSizeHints new_hints; + + new_hints = *(MetaSizeHints *) value->v.size_hints.hints; + scale_size_hints (window, &new_hints); + meta_window_set_normal_hints (window, &new_hints); + } + else + { + meta_window_set_normal_hints (window, NULL); + } hints_have_differences = hints_have_changed (&old_hints, &window->size_hints); diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index d02427f9e..947206059 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -111,6 +111,56 @@ meta_window_x11_get_private (MetaWindowX11 *window_x11) return meta_window_x11_get_instance_private (window_x11); } +static void +meta_window_x11_stage_to_protocol (MetaWindow *window, + int stage_x, + int stage_y, + int *protocol_x, + int *protocol_y) +{ + if (protocol_x) + *protocol_x = stage_x; + if (protocol_y) + *protocol_y = stage_y; +} + +static void +meta_window_x11_protocol_to_stage (MetaWindow *window, + int protocol_x, + int protocol_y, + int *stage_x, + int *stage_y, + MtkRoundingStrategy rounding_strategy) +{ + if (stage_x) + *stage_x = protocol_x; + if (stage_y) + *stage_y = protocol_y; +} + +static MtkRectangle * +protocol_rects_to_stage_rects (MetaWindow *window, + size_t n_rects, + XRectangle *protocol_rects) +{ + MtkRectangle *rects; + size_t i; + + rects = g_new0 (MtkRectangle, n_rects); + for (i = 0; i < n_rects; i++) + { + MtkRectangle protocol_rect = + MTK_RECTANGLE_INIT (protocol_rects[i].x, + protocol_rects[i].y, + protocol_rects[i].width, + protocol_rects[i].height); + + meta_window_protocol_to_stage_rect (window, &protocol_rect, &rects[i]); + } + + return rects; +} + static void send_icccm_message (MetaWindow *window, Atom atom, @@ -255,8 +305,11 @@ send_configure_notify (MetaWindow *window) event.xconfigure.display = x11_display->xdisplay; event.xconfigure.event = priv->xwindow; event.xconfigure.window = priv->xwindow; - event.xconfigure.x = priv->client_rect.x - priv->border_width; - event.xconfigure.y = priv->client_rect.y - priv->border_width; + meta_window_stage_to_protocol_point (window, + priv->client_rect.x - priv->border_width, + priv->client_rect.y - priv->border_width, + &event.xconfigure.x, + &event.xconfigure.y); if (priv->frame) { if (window->withdrawn) @@ -268,19 +321,36 @@ send_configure_notify (MetaWindow *window) meta_frame_calc_borders (priv->frame, &borders); - event.xconfigure.x = priv->frame->rect.x + borders.invisible.left; - event.xconfigure.y = priv->frame->rect.y + borders.invisible.top; + meta_window_stage_to_protocol_point (window, + (priv->frame->rect.x + + borders.invisible.left), + (priv->frame->rect.y + + borders.invisible.top), + &event.xconfigure.x, + &event.xconfigure.y); } else { + int dx, dy; + /* Need to be in root window coordinates */ - event.xconfigure.x += priv->frame->rect.x; - event.xconfigure.y += priv->frame->rect.y; + meta_window_stage_to_protocol_point (window, + priv->frame->rect.x, + priv->frame->rect.y, + &dx, + &dy); + event.xconfigure.x += dx; + event.xconfigure.y += dy; } } - event.xconfigure.width = priv->client_rect.width; - event.xconfigure.height = priv->client_rect.height; - event.xconfigure.border_width = priv->border_width; /* requested not actual */ + meta_window_stage_to_protocol_point (window, + priv->client_rect.width, + priv->client_rect.height, + &event.xconfigure.width, + &event.xconfigure.height); + meta_window_stage_to_protocol_point (window, + priv->border_width, 0, + &event.xconfigure.border_width, NULL); event.xconfigure.above = None; /* FIXME */ event.xconfigure.override_redirect = False; @@ -1150,20 +1220,27 @@ update_net_frame_extents (MetaWindow *window) MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaX11Display *x11_display = window->display->x11_display; - + int left, right, top, bottom; unsigned long data[4]; MetaFrameBorders borders; Window xwindow = meta_window_x11_get_xwindow (window); meta_frame_calc_borders (priv->frame, &borders); - /* Left */ - data[0] = borders.visible.left; - /* Right */ - data[1] = borders.visible.right; - /* Top */ - data[2] = borders.visible.top; - /* Bottom */ - data[3] = borders.visible.bottom; + meta_window_stage_to_protocol_point (window, + borders.visible.left, + borders.visible.right, + &left, + &right); + meta_window_stage_to_protocol_point (window, + borders.visible.top, + borders.visible.bottom, + &top, + &bottom); + + data[0] = left; + data[1] = right; + data[2] = top; + data[3] = bottom; meta_topic (META_DEBUG_GEOMETRY, "Setting _NET_FRAME_EXTENTS on managed window 0x%lx " @@ -1321,6 +1398,7 @@ meta_window_x11_move_resize_internal (MetaWindow *window, MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaFrameBorders borders; MtkRectangle client_rect; + MtkRectangle values_rect; int size_dx, size_dy; XWindowChanges values; unsigned int mask; @@ -1495,11 +1573,12 @@ meta_window_x11_move_resize_internal (MetaWindow *window, else configure_frame_first = size_dx + size_dy >= 0; + meta_window_stage_to_protocol_rect (window, &client_rect, &values_rect); values.border_width = 0; - values.x = client_rect.x; - values.y = client_rect.y; - values.width = client_rect.width; - values.height = client_rect.height; + values.x = values_rect.x; + values.y = values_rect.y; + values.width = values_rect.width; + values.height = values_rect.height; mask = 0; if (is_configure_request && priv->border_width != 0) @@ -1603,6 +1682,17 @@ meta_window_x11_update_struts (MetaWindow *window) strut_begin = struts[4+(i*2)]; strut_end = struts[4+(i*2)+1]; + meta_window_protocol_to_stage_point (window, + strut_begin, 0, + &strut_begin, NULL, + MTK_ROUNDING_STRATEGY_SHRINK); + meta_window_protocol_to_stage_point (window, + strut_end, + thickness, + &strut_end, + &thickness, + MTK_ROUNDING_STRATEGY_GROW); + temp = g_new0 (MetaStrut, 1); temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */ meta_display_get_size (window->display, @@ -1667,6 +1757,11 @@ meta_window_x11_update_struts (MetaWindow *window) if (thickness == 0) continue; + meta_window_protocol_to_stage_point (window, + thickness, 0, + &thickness, NULL, + MTK_ROUNDING_STRATEGY_GROW); + temp = g_new0 (MetaStrut, 1); temp->side = 1 << i; meta_display_get_size (window->display, @@ -2060,9 +2155,10 @@ static void meta_window_x11_constructed (GObject *object) { MetaWindow *window = META_WINDOW (object); - MetaWindowX11 *x11_window = META_WINDOW_X11 (object); - MetaWindowX11Private *priv = meta_window_x11_get_instance_private (x11_window); + MetaWindowX11 *window_x11 = META_WINDOW_X11 (object); + MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); XWindowAttributes attrs = priv->attributes; + MtkRectangle rect; meta_verbose ("attrs->map_state = %d (%s)", attrs.map_state, @@ -2077,16 +2173,16 @@ meta_window_x11_constructed (GObject *object) window->client_type = META_WINDOW_CLIENT_TYPE_X11; window->override_redirect = attrs.override_redirect; - window->rect.x = attrs.x; - window->rect.y = attrs.y; - window->rect.width = attrs.width; - window->rect.height = attrs.height; + rect = MTK_RECTANGLE_INIT (attrs.x, attrs.y, attrs.width, attrs.height); + meta_window_protocol_to_stage_rect (window, &rect, &rect); + + window->rect = rect; /* size_hints are the "request" */ - window->size_hints.x = attrs.x; - window->size_hints.y = attrs.y; - window->size_hints.width = attrs.width; - window->size_hints.height = attrs.height; + window->size_hints.x = rect.x; + window->size_hints.y = rect.y; + window->size_hints.width = rect.width; + window->size_hints.height = rect.height; window->depth = attrs.depth; priv->xvisual = attrs.visual; @@ -2097,11 +2193,12 @@ meta_window_x11_constructed (GObject *object) priv->frame = NULL; window->decorated = TRUE; window->hidden = FALSE; - priv->border_width = attrs.border_width; priv->xclient_leader = None; - priv->keys_grabbed = FALSE; - priv->grab_on_frame = FALSE; + meta_window_protocol_to_stage_point (window, + attrs.border_width, 0, + &priv->border_width, NULL, + MTK_ROUNDING_STRATEGY_GROW); g_signal_connect (window, "notify::decorated", G_CALLBACK (meta_window_x11_update_input_region), @@ -2210,6 +2307,8 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->calculate_layer = meta_window_x11_calculate_layer; window_class->is_focus_async = meta_window_x11_is_focus_async; window_class->set_transient_for = meta_window_x11_set_transient_for; + window_class->stage_to_protocol = meta_window_x11_stage_to_protocol; + window_class->protocol_to_stage = meta_window_x11_protocol_to_stage; klass->freeze_commits = meta_window_x11_impl_freeze_commits; klass->thaw_commits = meta_window_x11_impl_thaw_commits; @@ -2359,24 +2458,6 @@ meta_window_x11_set_net_wm_state (MetaWindow *window) update_gtk_edge_constraints (window); } -static MtkRegion * -region_create_from_x_rectangles (const XRectangle *rects, - int n_rects) -{ - int i; - MtkRectangle *mtk_rects = g_newa (MtkRectangle, n_rects); - - for (i = 0; i < n_rects; i++) - { - mtk_rects[i].x = rects[i].x; - mtk_rects[i].y = rects[i].y; - mtk_rects[i].width = rects[i].width; - mtk_rects[i].height = rects[i].height; - } - - return mtk_region_create_rectangles (mtk_rects, n_rects); -} - static void meta_window_set_input_region (MetaWindow *window, MtkRegion *region) @@ -2449,15 +2530,16 @@ meta_window_x11_update_input_region (MetaWindow *window) { /* Translate the set of XShape rectangles that we * get from the X server to a MtkRegion. */ - XRectangle *rects = NULL; + XRectangle *protocol_rects = NULL; + g_autoptr (MtkRectangle) rects = NULL; int n_rects = -1, ordering; mtk_x11_error_trap_push (x11_display->xdisplay); - rects = XShapeGetRectangles (x11_display->xdisplay, - xwindow, - ShapeInput, - &n_rects, - &ordering); + protocol_rects = XShapeGetRectangles (x11_display->xdisplay, + xwindow, + ShapeInput, + &n_rects, + &ordering); mtk_x11_error_trap_pop (x11_display->xdisplay); /* XXX: The X Shape specification is quite unfortunately specified. @@ -2473,6 +2555,9 @@ meta_window_x11_update_input_region (MetaWindow *window) * hey, it's X11! */ + if (n_rects >= 1) + rects = protocol_rects_to_stage_rects (window, n_rects, protocol_rects); + if (n_rects == -1) { /* We had an error. */ @@ -2496,10 +2581,10 @@ meta_window_x11_update_input_region (MetaWindow *window) else { /* Window has a custom shape. */ - region = region_create_from_x_rectangles (rects, n_rects); + region = mtk_region_create_rectangles (rects, n_rects); } - meta_XFree (rects); + meta_XFree (protocol_rects); } if (region != NULL) @@ -2546,7 +2631,7 @@ meta_window_x11_update_shape_region (MetaWindow *window) { /* Translate the set of XShape rectangles that we * get from the X server to a MtkRegion. */ - XRectangle *rects = NULL; + XRectangle *protocol_rects = NULL; int n_rects, ordering; int x_bounding, y_bounding, x_clip, y_clip; @@ -2562,18 +2647,22 @@ meta_window_x11_update_shape_region (MetaWindow *window) if (bounding_shaped) { - rects = XShapeGetRectangles (x11_display->xdisplay, - priv->xwindow, - ShapeBounding, - &n_rects, - &ordering); + protocol_rects = XShapeGetRectangles (x11_display->xdisplay, + priv->xwindow, + ShapeBounding, + &n_rects, + &ordering); } mtk_x11_error_trap_pop (x11_display->xdisplay); - if (rects) + if (protocol_rects) { - region = region_create_from_x_rectangles (rects, n_rects); - XFree (rects); + g_autoptr (MtkRectangle) rects = NULL; + + rects = protocol_rects_to_stage_rects (window, n_rects, protocol_rects); + region = mtk_region_create_rectangles (rects, n_rects); + + XFree (protocol_rects); } } @@ -2959,6 +3048,7 @@ meta_window_x11_configure_request (MetaWindow *window, { MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); + MtkRectangle rect; /* Note that x, y is the corner of the window border, * and width, height is the size of the window inside @@ -2967,15 +3057,24 @@ meta_window_x11_configure_request (MetaWindow *window, * requested border here. */ if (event->xconfigurerequest.value_mask & CWBorderWidth) - priv->border_width = event->xconfigurerequest.border_width; + { + meta_window_protocol_to_stage_point (window, + event->xconfigurerequest.border_width, 0, + &priv->border_width, NULL, + MTK_ROUNDING_STRATEGY_GROW); + } - meta_window_move_resize_request(window, - event->xconfigurerequest.value_mask, - window->size_hints.win_gravity, - event->xconfigurerequest.x, - event->xconfigurerequest.y, - event->xconfigurerequest.width, - event->xconfigurerequest.height); + rect = MTK_RECTANGLE_INIT (event->xconfigurerequest.x, event->xconfigurerequest.y, + event->xconfigurerequest.width, event->xconfigurerequest.height); + meta_window_protocol_to_stage_rect (window, &rect, &rect); + + meta_window_move_resize_request (window, + event->xconfigurerequest.value_mask, + window->size_hints.win_gravity, + rect.x, + rect.y, + rect.width, + rect.height); /* Handle stacking. We only handle raises/lowers, mostly because * stack.c really can't deal with anything else. I guess we'll fix @@ -3471,8 +3570,12 @@ meta_window_x11_client_message (MetaWindow *window, guint32 timestamp; MetaWindowDrag *window_drag; - x_root = event->xclient.data.l[0]; - y_root = event->xclient.data.l[1]; + meta_window_protocol_to_stage_point (window, + event->xclient.data.l[0], + event->xclient.data.l[1], + &x_root, + &y_root, + MTK_ROUNDING_STRATEGY_SHRINK); action = event->xclient.data.l[2]; button = event->xclient.data.l[3]; @@ -3636,6 +3739,7 @@ meta_window_x11_client_message (MetaWindow *window, { MetaGravity gravity; guint value_mask; + MtkRectangle rect; gravity = (MetaGravity) (event->xclient.data.l[0] & 0xff); value_mask = (event->xclient.data.l[0] & 0xf00) >> 8; @@ -3644,13 +3748,19 @@ meta_window_x11_client_message (MetaWindow *window, if (gravity == 0) gravity = window->size_hints.win_gravity; + rect = MTK_RECTANGLE_INIT (event->xclient.data.l[1], + event->xclient.data.l[2], + event->xclient.data.l[3], + event->xclient.data.l[4]); + meta_window_protocol_to_stage_rect (window, &rect, &rect); + meta_window_move_resize_request(window, value_mask, gravity, - event->xclient.data.l[1], /* x */ - event->xclient.data.l[2], /* y */ - event->xclient.data.l[3], /* width */ - event->xclient.data.l[4]); /* height */ + rect.x, + rect.y, + rect.width, + rect.height); } else if (event->xclient.message_type == x11_display->atom__NET_ACTIVE_WINDOW && @@ -3707,11 +3817,14 @@ meta_window_x11_client_message (MetaWindow *window, else if (event->xclient.message_type == x11_display->atom__GTK_SHOW_WINDOW_MENU) { - gulong x, y; + int x, y; /* l[0] is device_id, which we don't use */ - x = event->xclient.data.l[1]; - y = event->xclient.data.l[2]; + meta_window_protocol_to_stage_point (window, + event->xclient.data.l[1], + event->xclient.data.l[2], + &x, &y, + MTK_ROUNDING_STRATEGY_SHRINK); meta_window_show_menu (window, META_WINDOW_MENU_WM, x, y); } @@ -4237,10 +4350,12 @@ meta_window_x11_configure_notify (MetaWindow *window, g_assert (window->override_redirect); g_assert (priv->frame == NULL); - window->rect.x = event->x; - window->rect.y = event->y; - window->rect.width = event->width; - window->rect.height = event->height; + meta_window_protocol_to_stage_rect (window, + &MTK_RECTANGLE_INIT (event->x, + event->y, + event->width, + event->height), + &window->rect); priv->client_rect = window->rect; window->buffer_rect = window->rect;