diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index f9cd9ae31..763853c6a 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -293,6 +293,9 @@ MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_at (MetaMonitorMana MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, MetaRectangle *rect); +MetaLogicalMonitor *meta_monitor_manager_get_highest_scale_monitor_from_rect (MetaMonitorManager *manager, + MetaRectangle *rect); + MetaLogicalMonitor *meta_monitor_manager_get_logical_monitor_neighbor (MetaMonitorManager *manager, MetaLogicalMonitor *logical_monitor, MetaDisplayDirection direction); diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index bd02c55bb..cea76b71b 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -3399,6 +3399,47 @@ meta_monitor_manager_get_logical_monitor_from_rect (MetaMonitorManager *manager, return best_logical_monitor; } +/** + * meta_monitor_manager_get_highest_scale_from_rect: + * @manager: A #MetaMonitorManager object + * @rect: The rectangle + * + * Finds the #MetaLogicalMonitor with the highest scale intersecting @rect. + * + * Returns: (transfer none) (nullable): the #MetaLogicalMonitor with the + * highest scale intersecting with @rect, or %NULL if none. + */ +MetaLogicalMonitor * +meta_monitor_manager_get_highest_scale_monitor_from_rect (MetaMonitorManager *manager, + MetaRectangle *rect) +{ + MetaLogicalMonitor *best_logical_monitor = NULL; + GList *l; + float best_scale = 0.0; + + for (l = manager->logical_monitors; l; l = l->next) + { + MetaLogicalMonitor *logical_monitor = l->data; + MetaRectangle intersection; + float scale; + + if (!meta_rectangle_intersect (&logical_monitor->rect, + rect, + &intersection)) + continue; + + scale = meta_logical_monitor_get_scale (logical_monitor); + + if (scale > best_scale) + { + best_scale = scale; + best_logical_monitor = logical_monitor; + } + } + + return best_logical_monitor; +} + MetaLogicalMonitor * meta_monitor_manager_get_logical_monitor_neighbor (MetaMonitorManager *manager, MetaLogicalMonitor *logical_monitor, diff --git a/src/core/window-private.h b/src/core/window-private.h index 1c1215972..58ff69324 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -168,6 +168,7 @@ struct _MetaWindow uint64_t id; guint64 stamp; MetaLogicalMonitor *monitor; + MetaLogicalMonitor *highest_scale_monitor; MetaWorkspace *workspace; MetaWindowClientType client_type; Window xwindow; @@ -828,6 +829,7 @@ MetaLogicalMonitor * meta_window_find_monitor_from_frame_rect (MetaWindow *windo MetaLogicalMonitor * meta_window_find_monitor_from_id (MetaWindow *window); MetaLogicalMonitor * meta_window_get_main_logical_monitor (MetaWindow *window); +MetaLogicalMonitor * meta_window_get_highest_scale_monitor (MetaWindow *window); void meta_window_update_monitor (MetaWindow *window, MetaWindowUpdateMonitorFlags flags); diff --git a/src/core/window.c b/src/core/window.c index 40cc7b7da..4b8ae434d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -221,6 +221,7 @@ enum SIZE_CHANGED, POSITION_CHANGED, SHOWN, + HIGHEST_SCALE_MONITOR_CHANGED, LAST_SIGNAL }; @@ -755,6 +756,21 @@ meta_window_class_init (MetaWindowClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 0); + + /** + * MetaWindow::highest-scale-monitor-changed: + * @window: a #MetaWindow + * + * This is emitted when the monitor with the highest scale + * intersecting the window changes. + */ + window_signals[HIGHEST_SCALE_MONITOR_CHANGED] = + g_signal_new ("highest-scale-monitor-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 0); } static void @@ -1007,6 +1023,19 @@ meta_window_find_monitor_from_frame_rect (MetaWindow *window) &window_rect); } +static MetaLogicalMonitor * +meta_window_find_highest_scale_monitor_from_frame_rect (MetaWindow *window) +{ + MetaBackend *backend = backend_from_window (window); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaRectangle window_rect; + + meta_window_get_frame_rect (window, &window_rect); + return meta_monitor_manager_get_highest_scale_monitor_from_rect (monitor_manager, + &window_rect); +} + static void meta_window_manage (MetaWindow *window) { @@ -1152,6 +1181,9 @@ meta_window_constructed (GObject *object) else window->monitor = meta_backend_get_current_logical_monitor (backend); + window->highest_scale_monitor = + meta_window_find_highest_scale_monitor_from_frame_rect (window); + if (window->monitor) window->preferred_output_winsys_id = window->monitor->winsys_id; else @@ -3573,6 +3605,12 @@ meta_window_get_main_logical_monitor (MetaWindow *window) return window->monitor; } +MetaLogicalMonitor * +meta_window_get_highest_scale_monitor (MetaWindow *window) +{ + return window->highest_scale_monitor; +} + static MetaLogicalMonitor * find_monitor_by_winsys_id (MetaWindow *window, uint64_t winsys_id) @@ -3684,7 +3722,7 @@ meta_window_update_monitor (MetaWindow *window, MetaWindowUpdateMonitorFlags flags) { MetaWorkspaceManager *workspace_manager = window->display->workspace_manager; - const MetaLogicalMonitor *old; + const MetaLogicalMonitor *old, *old_highest_scale; old = window->monitor; META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags); @@ -3715,6 +3753,12 @@ meta_window_update_monitor (MetaWindow *window, meta_display_queue_check_fullscreen (window->display); } + + old_highest_scale = window->highest_scale_monitor; + window->highest_scale_monitor = + meta_window_find_highest_scale_monitor_from_frame_rect (window); + if (old_highest_scale != window->highest_scale_monitor) + g_signal_emit (window, window_signals[HIGHEST_SCALE_MONITOR_CHANGED], 0); } void