window: Keep proportional position in meta_window_move_between_rects
The previous logic tried to keep the position of the top left corner of the window relative to the top left corner of the monitor. This allowed the window to move out of the target monitor. This change keeps the proportions of the distance between the window and the monitor borders instead if possible. Otherwise it keeps the relative position of the center of the window clamped to [0,1] to make sure the window lands on the right output. This also slightly changes what monitor is considered to be on: the monitor which contains the center of the window and, if the center is on no monitor, the monitor wich overlaps the most with the window. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2591>
This commit is contained in:
parent
cd1ab57e68
commit
ec58e74cc5
@ -3268,8 +3268,9 @@ meta_monitor_manager_get_logical_monitor_at (MetaMonitorManager *manager,
|
|||||||
* @manager: A #MetaMonitorManager object
|
* @manager: A #MetaMonitorManager object
|
||||||
* @rect: The rectangle
|
* @rect: The rectangle
|
||||||
*
|
*
|
||||||
* Finds the #MetaLogicalMonitor which has the largest area in common with the
|
* Finds the #MetaLogicalMonitor which contains the center of the given @rect
|
||||||
* given @rect in the total layout.
|
* 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
|
* Returns: (transfer none) (nullable): The #MetaLogicalMonitor which
|
||||||
* corresponds the most to the given @rect, or %NULL if none.
|
* 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;
|
MetaLogicalMonitor *best_logical_monitor;
|
||||||
int best_logical_monitor_area;
|
int best_logical_monitor_area;
|
||||||
GList *l;
|
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 = NULL;
|
||||||
best_logical_monitor_area = 0;
|
best_logical_monitor_area = 0;
|
||||||
@ -3291,6 +3294,9 @@ meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager,
|
|||||||
MetaRectangle intersection;
|
MetaRectangle intersection;
|
||||||
int intersection_area;
|
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,
|
if (!meta_rectangle_intersect (&logical_monitor->rect,
|
||||||
rect,
|
rect,
|
||||||
&intersection))
|
&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)
|
if (!best_logical_monitor)
|
||||||
best_logical_monitor = manager->primary_logical_monitor;
|
best_logical_monitor = manager->primary_logical_monitor;
|
||||||
|
|
||||||
|
@ -4003,30 +4003,56 @@ meta_window_move_frame (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_window_move_between_rects (MetaWindow *window,
|
meta_window_move_between_rects (MetaWindow *window,
|
||||||
MetaMoveResizeFlags move_resize_flags,
|
MetaMoveResizeFlags move_resize_flags,
|
||||||
const MetaRectangle *old_area,
|
const MetaRectangle *old_area,
|
||||||
const MetaRectangle *new_area)
|
const MetaRectangle *new_area)
|
||||||
{
|
{
|
||||||
int rel_x, rel_y;
|
double rel_x, rel_y;
|
||||||
double scale_x, scale_y;
|
int new_x, new_y;
|
||||||
|
|
||||||
if (old_area)
|
if (!old_area)
|
||||||
{
|
{
|
||||||
rel_x = window->unconstrained_rect.x - old_area->x;
|
new_x = new_area->x;
|
||||||
rel_y = window->unconstrained_rect.y - old_area->y;
|
new_y = new_area->y;
|
||||||
scale_x = (double)new_area->width / old_area->width;
|
}
|
||||||
scale_y = (double)new_area->height / old_area->height;
|
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
|
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.x = new_x;
|
||||||
window->unconstrained_rect.y = new_area->y + rel_y * scale_y;
|
window->unconstrained_rect.y = new_y;
|
||||||
window->saved_rect.x = window->unconstrained_rect.x;
|
|
||||||
window->saved_rect.y = window->unconstrained_rect.y;
|
|
||||||
|
|
||||||
meta_window_move_resize_internal (window,
|
meta_window_move_resize_internal (window,
|
||||||
(move_resize_flags |
|
(move_resize_flags |
|
||||||
|
Loading…
x
Reference in New Issue
Block a user