diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index df9fe399d..3a09782a1 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -3268,8 +3268,9 @@ meta_monitor_manager_get_logical_monitor_at (MetaMonitorManager *manager, * @manager: A #MetaMonitorManager object * @rect: The rectangle * - * Finds the #MetaLogicalMonitor which has the largest area in common with the - * given @rect in the total layout. + * Finds the #MetaLogicalMonitor which contains the center of the given @rect + * or which has the largest area in common with the given @rect in the total + * layout if the center is not on a monitor. * * Returns: (transfer none) (nullable): The #MetaLogicalMonitor which * corresponds the most to the given @rect, or %NULL if none. @@ -3281,6 +3282,8 @@ meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, MetaLogicalMonitor *best_logical_monitor; int best_logical_monitor_area; GList *l; + int center_x = rect->x + (rect->width / 2); + int center_y = rect->y + (rect->height / 2); best_logical_monitor = NULL; best_logical_monitor_area = 0; @@ -3291,6 +3294,9 @@ meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, MetaRectangle intersection; int intersection_area; + if (META_POINT_IN_RECT (center_x, center_y, logical_monitor->rect)) + return logical_monitor; + if (!meta_rectangle_intersect (&logical_monitor->rect, rect, &intersection)) @@ -3305,10 +3311,6 @@ meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, } } - if (!best_logical_monitor && (rect->width == 0 || rect->height == 0)) - best_logical_monitor = - meta_monitor_manager_get_logical_monitor_at (manager, rect->x, rect->y); - if (!best_logical_monitor) best_logical_monitor = manager->primary_logical_monitor; diff --git a/src/core/window.c b/src/core/window.c index f04e6c8e5..ee2dec30e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4003,30 +4003,56 @@ meta_window_move_frame (MetaWindow *window, } static void -meta_window_move_between_rects (MetaWindow *window, +meta_window_move_between_rects (MetaWindow *window, MetaMoveResizeFlags move_resize_flags, const MetaRectangle *old_area, const MetaRectangle *new_area) { - int rel_x, rel_y; - double scale_x, scale_y; + double rel_x, rel_y; + int new_x, new_y; - if (old_area) + if (!old_area) { - rel_x = window->unconstrained_rect.x - old_area->x; - rel_y = window->unconstrained_rect.y - old_area->y; - scale_x = (double)new_area->width / old_area->width; - scale_y = (double)new_area->height / old_area->height; + new_x = new_area->x; + new_y = new_area->y; + } + else if (meta_rectangle_contains_rect (old_area, &window->unconstrained_rect) && + old_area->width > window->unconstrained_rect.width && + old_area->height > window->unconstrained_rect.height && + new_area->width >= window->unconstrained_rect.width && + new_area->height >= window->unconstrained_rect.height) + { + rel_x = (double)(window->unconstrained_rect.x - old_area->x) / + (old_area->width - window->unconstrained_rect.width); + rel_y = (double)(window->unconstrained_rect.y - old_area->y) / + (old_area->height - window->unconstrained_rect.height); + + g_warn_if_fail (rel_x >= 0.0 && rel_x <= 1.0 && + rel_y >= 0.0 && rel_y <= 1.0); + + new_x = new_area->x + + rel_x * (new_area->width - window->unconstrained_rect.width); + new_y = new_area->y + + rel_y * (new_area->height - window->unconstrained_rect.height); } else { - rel_x = rel_y = scale_x = scale_y = 0; + rel_x = (float)(window->unconstrained_rect.x - old_area->x + + (window->unconstrained_rect.width / 2)) / old_area->width; + rel_y = (float)(window->unconstrained_rect.y - old_area->y + + (window->unconstrained_rect.height / 2)) / old_area->height; + + rel_x = CLAMP (rel_x, FLT_EPSILON, 1.0 - FLT_EPSILON); + rel_y = CLAMP (rel_y, FLT_EPSILON, 1.0 - FLT_EPSILON); + + new_x = new_area->x - (window->unconstrained_rect.width / 2) + + (rel_x * new_area->width); + new_y = new_area->y - (window->unconstrained_rect.height / 2) + + (rel_y * new_area->height); } - window->unconstrained_rect.x = new_area->x + rel_x * scale_x; - window->unconstrained_rect.y = new_area->y + rel_y * scale_y; - window->saved_rect.x = window->unconstrained_rect.x; - window->saved_rect.y = window->unconstrained_rect.y; + window->unconstrained_rect.x = new_x; + window->unconstrained_rect.y = new_y; meta_window_move_resize_internal (window, (move_resize_flags |