mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
Add support for scaled logical monitor framebuffers
This commit adds support for rendering onto enlarged per logical monitor framebuffers, using the scaled clutter stage views, for HiDPI enabled logical monitors. This works by scaling the mode of the monitors in a logical monitors by the scale, no longer relying on scaling the window actors and window geometry for making windows have the correct size on HiDPI monitors. It is disabled by default, as in automatically created configurations will still use the old mode. This is partly because Xwayland clients will not yet work good enough to make it feasible. To enable, add the 'scale-monitor-framebuffer' keyword to the org.gnome.mutter.experimental-features gsettings array. It is still possible to specify the mode via the new D-Bus API, which has been adapted. The adaptations to the D-Bus API means the caller need to be aware of how to position logical monitors on the stage grid. This depends on the 'layout-mode' property that is used (see the DisplayConfig D-Bus documentation). https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
parent
094e0356e8
commit
8163ca6821
@ -112,7 +112,14 @@
|
||||
available, or configurable. Don't expect adding anything in this
|
||||
setting to be future proof.
|
||||
|
||||
Currently possible keywords: (none)
|
||||
Currently possible keywords:
|
||||
|
||||
* "scale-monitor-framebuffer" - makes mutter default to layout logical
|
||||
monitors in a logical pixel coordinate
|
||||
space, while scaling monitor
|
||||
framebuffers instead of window content,
|
||||
to manage HiDPI monitors. Does not
|
||||
require a restart.
|
||||
</description>
|
||||
</key>
|
||||
|
||||
|
@ -100,6 +100,7 @@ struct _MetaBackendClass
|
||||
typedef enum _MetaExperimentalFeature
|
||||
{
|
||||
META_EXPERIMENTAL_FEATURE_NONE = 0,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0)
|
||||
} MetaExperimentalFeature;
|
||||
|
||||
void meta_init_backend (GType backend_gtype);
|
||||
@ -161,6 +162,8 @@ void meta_backend_enable_experimental_feature (MetaBackend *backend,
|
||||
|
||||
gboolean meta_is_stage_views_enabled (void);
|
||||
|
||||
gboolean meta_is_stage_views_scaled (void);
|
||||
|
||||
MetaInputSettings *meta_backend_get_input_settings (MetaBackend *backend);
|
||||
|
||||
#endif /* META_BACKEND_PRIVATE_H */
|
||||
|
@ -428,7 +428,10 @@ experimental_features_handler (GVariant *features_variant,
|
||||
while (g_variant_iter_loop (&features_iter, "s", &feature))
|
||||
{
|
||||
/* So far no experimental features defined. */
|
||||
g_info ("Unknown experimental feature '%s'\n", feature);
|
||||
if (g_str_equal (feature, "scale-monitor-framebuffer"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
|
||||
else
|
||||
g_info ("Unknown experimental feature '%s'\n", feature);
|
||||
}
|
||||
|
||||
if (features != priv->experimental_features)
|
||||
@ -968,6 +971,22 @@ meta_is_stage_views_enabled (void)
|
||||
return !g_str_equal (mutter_stage_views, "0");
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_is_stage_views_scaled (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
|
||||
if (!meta_is_stage_views_enabled ())
|
||||
return FALSE;
|
||||
|
||||
layout_mode = monitor_manager->layout_mode;
|
||||
|
||||
return layout_mode == META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
||||
}
|
||||
|
||||
MetaInputSettings *
|
||||
meta_backend_get_input_settings (MetaBackend *backend)
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
|
||||
|
||||
logical_monitor->number = monitor_number;
|
||||
logical_monitor->winsys_id = main_output->winsys_id;
|
||||
logical_monitor->scale = logical_monitor_config->scale,
|
||||
logical_monitor->scale = logical_monitor_config->scale;
|
||||
logical_monitor->in_fullscreen = -1;
|
||||
logical_monitor->rect = logical_monitor_config->layout;
|
||||
|
||||
|
@ -60,9 +60,9 @@ G_DECLARE_FINAL_TYPE (MetaLogicalMonitor, meta_logical_monitor,
|
||||
META, LOGICAL_MONITOR,
|
||||
GObject)
|
||||
|
||||
MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
int monitor_number);
|
||||
MetaLogicalMonitor * meta_logical_monitor_new (MetaMonitorManager *monitor_manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
int monitor_number);
|
||||
|
||||
MetaLogicalMonitor * meta_logical_monitor_new_derived (MetaMonitorManager *monitor_manager,
|
||||
MetaMonitor *monitor,
|
||||
|
@ -51,8 +51,8 @@ meta_monitor_config_manager_new (MetaMonitorManager *monitor_manager)
|
||||
|
||||
config_manager = g_object_new (META_TYPE_MONITOR_CONFIG_MANAGER, NULL);
|
||||
config_manager->monitor_manager = monitor_manager;
|
||||
config_manager->config_store = g_object_new (META_TYPE_MONITOR_CONFIG_STORE,
|
||||
NULL);
|
||||
config_manager->config_store =
|
||||
meta_monitor_config_store_new (monitor_manager);
|
||||
|
||||
return config_manager;
|
||||
}
|
||||
@ -461,10 +461,11 @@ create_monitor_config (MetaMonitor *monitor,
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorConfig *
|
||||
create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
|
||||
MetaMonitor *monitor,
|
||||
int x,
|
||||
int y)
|
||||
create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
|
||||
MetaMonitor *monitor,
|
||||
int x,
|
||||
int y,
|
||||
MetaLogicalMonitorLayoutMode layout_mode)
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
int width, height;
|
||||
@ -478,6 +479,16 @@ create_preferred_logical_monitor_config (MetaMonitorManager *monitor_manager,
|
||||
monitor,
|
||||
mode);
|
||||
|
||||
switch (layout_mode)
|
||||
{
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
|
||||
width /= scale;
|
||||
height /= scale;
|
||||
break;
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
|
||||
break;
|
||||
}
|
||||
|
||||
monitor_config = create_monitor_config (monitor, mode);
|
||||
|
||||
logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1);
|
||||
@ -501,6 +512,7 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
|
||||
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
||||
GList *logical_monitor_configs;
|
||||
MetaMonitor *primary_monitor;
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
MetaLogicalMonitorConfig *primary_logical_monitor_config;
|
||||
int x;
|
||||
GList *monitors;
|
||||
@ -510,10 +522,13 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
|
||||
if (!primary_monitor)
|
||||
return NULL;
|
||||
|
||||
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
|
||||
|
||||
primary_logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (monitor_manager,
|
||||
primary_monitor,
|
||||
0, 0);
|
||||
0, 0,
|
||||
layout_mode);
|
||||
primary_logical_monitor_config->is_primary = TRUE;
|
||||
logical_monitor_configs = g_list_append (NULL,
|
||||
primary_logical_monitor_config);
|
||||
@ -535,14 +550,15 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
|
||||
logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (monitor_manager,
|
||||
monitor,
|
||||
x, 0);
|
||||
x, 0,
|
||||
layout_mode);
|
||||
logical_monitor_configs = g_list_append (logical_monitor_configs,
|
||||
logical_monitor_config);
|
||||
|
||||
x += logical_monitor_config->layout.width;
|
||||
}
|
||||
|
||||
return meta_monitors_config_new (logical_monitor_configs);
|
||||
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
|
||||
}
|
||||
|
||||
MetaMonitorsConfig *
|
||||
@ -551,21 +567,25 @@ meta_monitor_config_manager_create_fallback (MetaMonitorConfigManager *config_ma
|
||||
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
||||
MetaMonitor *primary_monitor;
|
||||
GList *logical_monitor_configs;
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
MetaLogicalMonitorConfig *primary_logical_monitor_config;
|
||||
|
||||
primary_monitor = find_primary_monitor (monitor_manager);
|
||||
if (!primary_monitor)
|
||||
return NULL;
|
||||
|
||||
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
|
||||
|
||||
primary_logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (monitor_manager,
|
||||
primary_monitor,
|
||||
0, 0);
|
||||
0, 0,
|
||||
layout_mode);
|
||||
primary_logical_monitor_config->is_primary = TRUE;
|
||||
logical_monitor_configs = g_list_append (NULL,
|
||||
primary_logical_monitor_config);
|
||||
|
||||
return meta_monitors_config_new (logical_monitor_configs);
|
||||
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
|
||||
}
|
||||
|
||||
MetaMonitorsConfig *
|
||||
@ -574,6 +594,7 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
|
||||
MetaMonitorManager *monitor_manager = config_manager->monitor_manager;
|
||||
MetaLogicalMonitorConfig *primary_logical_monitor_config = NULL;
|
||||
MetaMonitor *primary_monitor;
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
GList *logical_monitor_configs;
|
||||
GList *region;
|
||||
GList *monitors;
|
||||
@ -583,6 +604,8 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
|
||||
if (!primary_monitor)
|
||||
return NULL;
|
||||
|
||||
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
|
||||
|
||||
logical_monitor_configs = NULL;
|
||||
region = NULL;
|
||||
monitors = meta_monitor_manager_get_monitors (monitor_manager);
|
||||
@ -598,7 +621,8 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
|
||||
logical_monitor_config =
|
||||
create_preferred_logical_monitor_config (monitor_manager,
|
||||
monitor,
|
||||
x, y);
|
||||
x, y,
|
||||
layout_mode);
|
||||
logical_monitor_configs = g_list_append (logical_monitor_configs,
|
||||
logical_monitor_config);
|
||||
|
||||
@ -629,7 +653,7 @@ meta_monitor_config_manager_create_suggested (MetaMonitorConfigManager *config_m
|
||||
|
||||
primary_logical_monitor_config->is_primary = TRUE;
|
||||
|
||||
return meta_monitors_config_new (logical_monitor_configs);
|
||||
return meta_monitors_config_new (logical_monitor_configs, layout_mode);
|
||||
}
|
||||
|
||||
void
|
||||
@ -774,13 +798,15 @@ meta_monitors_config_key_equal (gconstpointer data_a,
|
||||
}
|
||||
|
||||
MetaMonitorsConfig *
|
||||
meta_monitors_config_new (GList *logical_monitor_configs)
|
||||
meta_monitors_config_new (GList *logical_monitor_configs,
|
||||
MetaLogicalMonitorLayoutMode layout_mode)
|
||||
{
|
||||
MetaMonitorsConfig *config;
|
||||
|
||||
config = g_object_new (META_TYPE_MONITORS_CONFIG, NULL);
|
||||
config->logical_monitor_configs = logical_monitor_configs;
|
||||
config->key = meta_monitors_config_key_new (logical_monitor_configs);
|
||||
config->layout_mode = layout_mode;
|
||||
|
||||
return config;
|
||||
}
|
||||
@ -862,12 +888,13 @@ meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
GError **error)
|
||||
meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
MetaLogicalMonitorLayoutMode layout_mode,
|
||||
GError **error)
|
||||
{
|
||||
GList *l;
|
||||
int layout_width;
|
||||
int layout_height;
|
||||
int expected_mode_width = 0;
|
||||
int expected_mode_height = 0;
|
||||
|
||||
if (logical_monitor_config->scale < 1)
|
||||
{
|
||||
@ -894,14 +921,26 @@ meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_co
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
layout_width = logical_monitor_config->layout.width;
|
||||
layout_height = logical_monitor_config->layout.height;
|
||||
switch (layout_mode)
|
||||
{
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
|
||||
expected_mode_width = (logical_monitor_config->layout.width *
|
||||
logical_monitor_config->scale);
|
||||
expected_mode_height = (logical_monitor_config->layout.height *
|
||||
logical_monitor_config->scale);
|
||||
break;
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
|
||||
expected_mode_width = logical_monitor_config->layout.width;
|
||||
expected_mode_height = logical_monitor_config->layout.height;
|
||||
break;
|
||||
}
|
||||
|
||||
for (l = logical_monitor_config->monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = l->data;
|
||||
|
||||
if (monitor_config->mode_spec->width != layout_width ||
|
||||
monitor_config->mode_spec->height != layout_height)
|
||||
if (monitor_config->mode_spec->width != expected_mode_width ||
|
||||
monitor_config->mode_spec->height != expected_mode_height)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Monitor modes in logical monitor conflict");
|
||||
|
@ -56,6 +56,8 @@ struct _MetaMonitorsConfig
|
||||
|
||||
MetaMonitorsConfigKey *key;
|
||||
GList *logical_monitor_configs;
|
||||
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
};
|
||||
|
||||
#define META_TYPE_MONITORS_CONFIG (meta_monitors_config_get_type ())
|
||||
@ -85,7 +87,8 @@ void meta_monitor_config_manager_set_current (MetaMonitorConfigManager *config_m
|
||||
|
||||
MetaMonitorsConfig * meta_monitor_config_manager_get_current (MetaMonitorConfigManager *config_manager);
|
||||
|
||||
MetaMonitorsConfig * meta_monitors_config_new (GList *logical_monitor_configs);
|
||||
MetaMonitorsConfig * meta_monitors_config_new (GList *logical_monitor_configs,
|
||||
MetaLogicalMonitorLayoutMode layout_mode);
|
||||
|
||||
unsigned int meta_monitors_config_key_hash (gconstpointer config_key);
|
||||
|
||||
@ -107,8 +110,9 @@ gboolean meta_verify_monitor_spec (MetaMonitorSpec *monitor_spec,
|
||||
gboolean meta_verify_monitor_config (MetaMonitorConfig *monitor_config,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
GError **error);
|
||||
gboolean meta_verify_logical_monitor_config (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
MetaLogicalMonitorLayoutMode layout_mode,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_verify_monitors_config (MetaMonitorsConfig *config,
|
||||
GError **error);
|
||||
|
@ -81,6 +81,8 @@ struct _MetaMonitorConfigStore
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaMonitorManager *monitor_manager;
|
||||
|
||||
GHashTable *configs;
|
||||
};
|
||||
|
||||
@ -355,11 +357,13 @@ handle_start_element (GMarkupParseContext *context,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
GError **error)
|
||||
derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
MetaLogicalMonitorLayoutMode layout_mode,
|
||||
GError **error)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config;
|
||||
int mode_width, mode_height;
|
||||
int width = 0, height = 0;
|
||||
GList *l;
|
||||
|
||||
monitor_config = logical_monitor_config->monitor_configs->data;
|
||||
@ -379,8 +383,19 @@ derive_logical_monitor_layout (MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
}
|
||||
}
|
||||
|
||||
logical_monitor_config->layout.width = mode_width;
|
||||
logical_monitor_config->layout.height = mode_height;
|
||||
switch (layout_mode)
|
||||
{
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
|
||||
width = mode_width / logical_monitor_config->scale;
|
||||
height = mode_height / logical_monitor_config->scale;
|
||||
break;
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
|
||||
width = mode_width;
|
||||
height = mode_height;
|
||||
}
|
||||
|
||||
logical_monitor_config->layout.width = width;
|
||||
logical_monitor_config->layout.height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -491,12 +506,6 @@ handle_end_element (GMarkupParseContext *context,
|
||||
if (logical_monitor_config->scale == 0)
|
||||
logical_monitor_config->scale = 1;
|
||||
|
||||
if (!derive_logical_monitor_layout (logical_monitor_config, error))
|
||||
return;
|
||||
|
||||
if (!meta_verify_logical_monitor_config (logical_monitor_config, error))
|
||||
return;
|
||||
|
||||
parser->current_logical_monitor_configs =
|
||||
g_list_append (parser->current_logical_monitor_configs,
|
||||
logical_monitor_config);
|
||||
@ -508,12 +517,34 @@ handle_end_element (GMarkupParseContext *context,
|
||||
|
||||
case STATE_CONFIGURATION:
|
||||
{
|
||||
MetaMonitorConfigStore *store = parser->config_store;
|
||||
MetaMonitorsConfig *config;
|
||||
GList *l;
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
|
||||
g_assert (g_str_equal (element_name, "configuration"));
|
||||
|
||||
layout_mode =
|
||||
meta_monitor_manager_get_default_layout_mode (store->monitor_manager);
|
||||
|
||||
for (l = parser->current_logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
|
||||
if (!derive_logical_monitor_layout (logical_monitor_config,
|
||||
layout_mode,
|
||||
error))
|
||||
return;
|
||||
|
||||
if (!meta_verify_logical_monitor_config (logical_monitor_config,
|
||||
layout_mode,
|
||||
error))
|
||||
return;
|
||||
}
|
||||
|
||||
config =
|
||||
meta_monitors_config_new (parser->current_logical_monitor_configs);
|
||||
meta_monitors_config_new (parser->current_logical_monitor_configs,
|
||||
layout_mode);
|
||||
|
||||
if (!meta_verify_monitors_config (config, error))
|
||||
{
|
||||
@ -852,6 +883,17 @@ meta_monitor_config_store_get_config_count (MetaMonitorConfigStore *config_store
|
||||
return (int) g_hash_table_size (config_store->configs);
|
||||
}
|
||||
|
||||
MetaMonitorConfigStore *
|
||||
meta_monitor_config_store_new (MetaMonitorManager *monitor_manager)
|
||||
{
|
||||
MetaMonitorConfigStore *store;
|
||||
|
||||
store = g_object_new (META_TYPE_MONITOR_CONFIG_STORE, NULL);
|
||||
store->monitor_manager = monitor_manager;
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_store_dispose (GObject *object)
|
||||
{
|
||||
|
@ -30,6 +30,8 @@
|
||||
G_DECLARE_FINAL_TYPE (MetaMonitorConfigStore, meta_monitor_config_store,
|
||||
META, MONITOR_CONFIG_STORE, GObject)
|
||||
|
||||
MetaMonitorConfigStore * meta_monitor_config_store_new (MetaMonitorManager *monitor_manager);
|
||||
|
||||
MetaMonitorsConfig * meta_monitor_config_store_lookup (MetaMonitorConfigStore *config_store,
|
||||
MetaMonitorsConfigKey *key);
|
||||
|
||||
|
@ -605,10 +605,30 @@ meta_monitor_manager_dummy_get_supported_scales (MetaMonitorManager *manager,
|
||||
*n_scales = G_N_ELEMENTS (supported_scales_dummy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_monitor_framebuffers_scaled (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
return meta_backend_is_experimental_feature_enabled (
|
||||
backend,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
|
||||
}
|
||||
|
||||
static MetaMonitorManagerCapability
|
||||
meta_monitor_manager_dummy_get_capabilities (MetaMonitorManager *manager)
|
||||
{
|
||||
return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
|
||||
MetaMonitorManagerCapability capabilities =
|
||||
META_MONITOR_MANAGER_CAPABILITY_NONE;
|
||||
|
||||
capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
|
||||
|
||||
if (meta_backend_is_experimental_feature_enabled (
|
||||
meta_get_backend (),
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
|
||||
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -625,6 +645,18 @@ meta_monitor_manager_dummy_get_max_screen_size (MetaMonitorManager *manager,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorLayoutMode
|
||||
meta_monitor_manager_dummy_get_default_layout_mode (MetaMonitorManager *manager)
|
||||
{
|
||||
if (!meta_is_stage_views_enabled ())
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
|
||||
if (is_monitor_framebuffers_scaled ())
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
||||
else
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
|
||||
{
|
||||
@ -639,6 +671,7 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
|
||||
manager_class->get_supported_scales = meta_monitor_manager_dummy_get_supported_scales;
|
||||
manager_class->get_capabilities = meta_monitor_manager_dummy_get_capabilities;
|
||||
manager_class->get_max_screen_size = meta_monitor_manager_dummy_get_max_screen_size;
|
||||
manager_class->get_default_layout_mode = meta_monitor_manager_dummy_get_default_layout_mode;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -71,7 +71,8 @@ typedef struct _MetaTileInfo MetaTileInfo;
|
||||
typedef enum _MetaMonitorManagerCapability
|
||||
{
|
||||
META_MONITOR_MANAGER_CAPABILITY_NONE = 0,
|
||||
META_MONITOR_MANAGER_CAPABILITY_MIRRORING = (1 << 0)
|
||||
META_MONITOR_MANAGER_CAPABILITY_MIRRORING = (1 << 0),
|
||||
META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE = (1 << 1)
|
||||
} MetaMonitorManagerCapability;
|
||||
|
||||
/* Equivalent to the 'method' enum in org.gnome.Mutter.DisplayConfig */
|
||||
@ -82,6 +83,13 @@ typedef enum _MetaMonitorsConfigMethod
|
||||
META_MONITORS_CONFIG_METHOD_PERSISTENT = 2
|
||||
} MetaMonitorsConfigMethod;
|
||||
|
||||
/* Equivalent to the 'layout-mode' enum in org.gnome.Mutter.DisplayConfig */
|
||||
typedef enum _MetaLogicalMonitorLayoutMode
|
||||
{
|
||||
META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL = 1,
|
||||
META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2
|
||||
} MetaLogicalMonitorLayoutMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_MONITOR_TRANSFORM_NORMAL,
|
||||
@ -274,6 +282,8 @@ struct _MetaMonitorManager
|
||||
|
||||
MetaPowerSave power_save_mode;
|
||||
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
|
||||
int screen_width;
|
||||
int screen_height;
|
||||
|
||||
@ -376,6 +386,8 @@ struct _MetaMonitorManagerClass
|
||||
gboolean (*get_max_screen_size) (MetaMonitorManager *,
|
||||
int *,
|
||||
int *);
|
||||
|
||||
MetaLogicalMonitorLayoutMode (*get_default_layout_mode) (MetaMonitorManager *);
|
||||
};
|
||||
|
||||
void meta_monitor_manager_rebuild (MetaMonitorManager *manager,
|
||||
@ -479,6 +491,9 @@ gboolean meta_monitor_manager_get_max_screen_size (MetaMonitorManager
|
||||
int *max_width,
|
||||
int *max_height);
|
||||
|
||||
MetaLogicalMonitorLayoutMode
|
||||
meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager);
|
||||
|
||||
void meta_monitor_manager_clear_output (MetaOutput *output);
|
||||
void meta_monitor_manager_clear_mode (MetaCrtcMode *mode);
|
||||
void meta_monitor_manager_clear_crtc (MetaCrtc *crtc);
|
||||
|
@ -319,6 +319,16 @@ meta_monitor_manager_get_max_screen_size (MetaMonitorManager *manager,
|
||||
return manager_class->get_max_screen_size (manager, max_width, max_height);
|
||||
}
|
||||
|
||||
|
||||
MetaLogicalMonitorLayoutMode
|
||||
meta_monitor_manager_get_default_layout_mode (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaMonitorManagerClass *manager_class =
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
|
||||
return manager_class->get_default_layout_mode (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -1397,6 +1407,13 @@ meta_monitor_manager_handle_get_current_state (MetaDBusDisplayConfig *skeleton,
|
||||
g_variant_new_boolean (FALSE));
|
||||
}
|
||||
|
||||
if (capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)
|
||||
{
|
||||
g_variant_builder_add (&properties_builder, "{sv}",
|
||||
"layout-mode",
|
||||
g_variant_new_uint32 (manager->layout_mode));
|
||||
}
|
||||
|
||||
if (meta_monitor_manager_get_max_screen_size (manager,
|
||||
&max_screen_width,
|
||||
&max_screen_height))
|
||||
@ -1593,10 +1610,12 @@ create_monitor_config_from_variant (MetaMonitorManager *manager,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
derive_logical_monitor_size (GList *monitor_configs,
|
||||
int *width,
|
||||
int *height,
|
||||
GError **error)
|
||||
derive_logical_monitor_size (GList *monitor_configs,
|
||||
int *width,
|
||||
int *height,
|
||||
double scale,
|
||||
MetaLogicalMonitorLayoutMode layout_mode,
|
||||
GError **error)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config;
|
||||
|
||||
@ -1608,16 +1627,27 @@ derive_logical_monitor_size (GList *monitor_configs,
|
||||
}
|
||||
|
||||
monitor_config = monitor_configs->data;
|
||||
*width = monitor_config->mode_spec->width;
|
||||
*height = monitor_config->mode_spec->height;
|
||||
|
||||
return TRUE;
|
||||
switch (layout_mode)
|
||||
{
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
|
||||
*width = monitor_config->mode_spec->width / scale;
|
||||
*height = monitor_config->mode_spec->height / scale;
|
||||
return TRUE;
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
|
||||
*width = monitor_config->mode_spec->width;
|
||||
*height = monitor_config->mode_spec->height;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorConfig *
|
||||
create_logical_monitor_config_from_variant (MetaMonitorManager *manager,
|
||||
GVariant *logical_monitor_config_variant,
|
||||
GError **error)
|
||||
create_logical_monitor_config_from_variant (MetaMonitorManager *manager,
|
||||
GVariant *logical_monitor_config_variant,
|
||||
MetaLogicalMonitorLayoutMode layout_mode,
|
||||
GError **error)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config;
|
||||
int x, y, width, height;
|
||||
@ -1658,7 +1688,8 @@ create_logical_monitor_config_from_variant (MetaMonitorManager *manager,
|
||||
}
|
||||
g_variant_iter_free (monitor_configs_iter);
|
||||
|
||||
if (!derive_logical_monitor_size (monitor_configs, &width, &height, error))
|
||||
if (!derive_logical_monitor_size (monitor_configs, &width, &height,
|
||||
scale, layout_mode, error))
|
||||
goto err;
|
||||
|
||||
logical_monitor_config = g_new0 (MetaLogicalMonitorConfig, 1);
|
||||
@ -1674,7 +1705,9 @@ create_logical_monitor_config_from_variant (MetaMonitorManager *manager,
|
||||
.monitor_configs = monitor_configs
|
||||
};
|
||||
|
||||
if (!meta_verify_logical_monitor_config (logical_monitor_config, error))
|
||||
if (!meta_verify_logical_monitor_config (logical_monitor_config,
|
||||
layout_mode,
|
||||
error))
|
||||
{
|
||||
meta_logical_monitor_config_free (logical_monitor_config);
|
||||
return NULL;
|
||||
@ -1687,6 +1720,19 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_valid_layout_mode (MetaLogicalMonitorLayoutMode layout_mode)
|
||||
{
|
||||
switch (layout_mode)
|
||||
{
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL:
|
||||
case META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
@ -1696,6 +1742,9 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
|
||||
GVariant *properties_variant)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
|
||||
MetaMonitorManagerCapability capabilities;
|
||||
GVariant *layout_mode_variant = NULL;
|
||||
MetaLogicalMonitorLayoutMode layout_mode;
|
||||
GVariantIter logical_monitor_configs_iter;
|
||||
MetaMonitorsConfig *config;
|
||||
GList *logical_monitor_configs = NULL;
|
||||
@ -1717,6 +1766,39 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
capabilities = meta_monitor_manager_get_capabilities (manager);
|
||||
|
||||
if (properties_variant)
|
||||
layout_mode_variant = g_variant_lookup_value (properties_variant,
|
||||
"layout-mode",
|
||||
G_VARIANT_TYPE ("u"));
|
||||
|
||||
if (layout_mode_variant &&
|
||||
capabilities & META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)
|
||||
{
|
||||
g_variant_get (layout_mode_variant, "u", &layout_mode);
|
||||
}
|
||||
else if (!layout_mode_variant)
|
||||
{
|
||||
layout_mode =
|
||||
meta_monitor_manager_get_default_layout_mode (manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Can't set layout mode");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!is_valid_layout_mode (layout_mode))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_ACCESS_DENIED,
|
||||
"Invalid layout mode specified");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_variant_iter_init (&logical_monitor_configs_iter,
|
||||
logical_monitor_configs_variant);
|
||||
while (TRUE)
|
||||
@ -1731,6 +1813,7 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
|
||||
logical_monitor_config =
|
||||
create_logical_monitor_config_from_variant (manager,
|
||||
logical_monitor_config_variant,
|
||||
layout_mode,
|
||||
&error);
|
||||
if (!logical_monitor_config)
|
||||
{
|
||||
@ -1747,7 +1830,7 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
|
||||
logical_monitor_config);
|
||||
}
|
||||
|
||||
config = meta_monitors_config_new (logical_monitor_configs);
|
||||
config = meta_monitors_config_new (logical_monitor_configs, layout_mode);
|
||||
if (!meta_verify_monitors_config (config, &error))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@ -2416,6 +2499,12 @@ void
|
||||
meta_monitor_manager_update_logical_state (MetaMonitorManager *manager,
|
||||
MetaMonitorsConfig *config)
|
||||
{
|
||||
if (config)
|
||||
manager->layout_mode = config->layout_mode;
|
||||
else
|
||||
manager->layout_mode =
|
||||
meta_monitor_manager_get_default_layout_mode (manager);
|
||||
|
||||
meta_monitor_manager_rebuild_logical_monitors (manager, config);
|
||||
}
|
||||
|
||||
@ -2455,6 +2544,8 @@ meta_monitor_manager_update_monitor_modes_derived (MetaMonitorManager *manager)
|
||||
void
|
||||
meta_monitor_manager_update_logical_state_derived (MetaMonitorManager *manager)
|
||||
{
|
||||
manager->layout_mode = META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
|
||||
meta_monitor_manager_rebuild_logical_monitors_derived (manager);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include <meta/meta-backend.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor.h"
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
#include "meta/boxes.h"
|
||||
@ -214,50 +216,125 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaCursorRendererNative *in_cursor_renderer_native;
|
||||
MetaLogicalMonitor *in_logical_monitor;
|
||||
MetaRectangle in_local_cursor_rect;
|
||||
MetaCursorSprite *in_cursor_sprite;
|
||||
|
||||
gboolean out_painted;
|
||||
} UpdateCrtcCursorData;
|
||||
|
||||
static gboolean
|
||||
update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
MetaMonitorMode *monitor_mode,
|
||||
MetaMonitorCrtcMode *monitor_crtc_mode,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
UpdateCrtcCursorData *data = user_data;
|
||||
MetaCursorRendererNative *cursor_renderer_native =
|
||||
data->in_cursor_renderer_native;
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
MetaRectangle scaled_crtc_rect;
|
||||
int scale;
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
scale = meta_logical_monitor_get_scale (data->in_logical_monitor);
|
||||
else
|
||||
scale = 1;
|
||||
|
||||
scaled_crtc_rect = (MetaRectangle) {
|
||||
.x = monitor_crtc_mode->x / scale,
|
||||
.y = monitor_crtc_mode->y / scale,
|
||||
.width = monitor_crtc_mode->crtc_mode->width / scale,
|
||||
.height = monitor_crtc_mode->crtc_mode->height / scale
|
||||
};
|
||||
|
||||
if (priv->has_hw_cursor &&
|
||||
meta_rectangle_overlap (&scaled_crtc_rect,
|
||||
&data->in_local_cursor_rect))
|
||||
{
|
||||
int crtc_cursor_x, crtc_cursor_y;
|
||||
|
||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||
monitor_crtc_mode->output->crtc,
|
||||
data->in_cursor_sprite);
|
||||
|
||||
crtc_cursor_x = (data->in_local_cursor_rect.x - scaled_crtc_rect.x) * scale;
|
||||
crtc_cursor_y = (data->in_local_cursor_rect.y - scaled_crtc_rect.y) * scale;
|
||||
drmModeMoveCursor (priv->drm_fd,
|
||||
monitor_crtc_mode->output->crtc->crtc_id,
|
||||
crtc_cursor_x,
|
||||
crtc_cursor_y);
|
||||
|
||||
data->out_painted = data->out_painted || TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||
monitor_crtc_mode->output->crtc, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_hw_cursor (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
MetaMonitorManager *monitors;
|
||||
MetaCrtc *crtcs;
|
||||
unsigned int i, n_crtcs;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
GList *logical_monitors;
|
||||
GList *l;
|
||||
MetaRectangle rect;
|
||||
gboolean painted = FALSE;
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
else
|
||||
rect = (MetaRectangle) { 0 };
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
logical_monitors =
|
||||
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
||||
for (l = logical_monitors; l; l = l->next)
|
||||
{
|
||||
gboolean crtc_should_use_cursor;
|
||||
MetaCursorSprite *crtc_cursor;
|
||||
MetaRectangle *crtc_rect;
|
||||
MetaLogicalMonitor *logical_monitor = l->data;
|
||||
UpdateCrtcCursorData data;
|
||||
GList *monitors;
|
||||
GList *k;
|
||||
|
||||
crtc_rect = &crtcs[i].rect;
|
||||
data = (UpdateCrtcCursorData) {
|
||||
.in_cursor_renderer_native = native,
|
||||
.in_logical_monitor = logical_monitor,
|
||||
.in_local_cursor_rect = (MetaRectangle) {
|
||||
.x = rect.x - logical_monitor->rect.x,
|
||||
.y = rect.y - logical_monitor->rect.y,
|
||||
.width = rect.width,
|
||||
.height = rect.height
|
||||
},
|
||||
.in_cursor_sprite = cursor_sprite
|
||||
};
|
||||
|
||||
crtc_should_use_cursor = (priv->has_hw_cursor &&
|
||||
meta_rectangle_overlap (&rect, crtc_rect));
|
||||
if (crtc_should_use_cursor)
|
||||
crtc_cursor = cursor_sprite;
|
||||
else
|
||||
crtc_cursor = NULL;
|
||||
|
||||
set_crtc_cursor (native, &crtcs[i], crtc_cursor);
|
||||
|
||||
if (crtc_cursor)
|
||||
monitors = meta_logical_monitor_get_monitors (logical_monitor);
|
||||
for (k = monitors; k; k = k->next)
|
||||
{
|
||||
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
|
||||
rect.x - crtc_rect->x,
|
||||
rect.y - crtc_rect->y);
|
||||
painted = TRUE;
|
||||
MetaMonitor *monitor = k->data;
|
||||
MetaMonitorMode *monitor_mode;
|
||||
|
||||
monitor_mode = meta_monitor_get_current_mode (monitor);
|
||||
meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
|
||||
update_monitor_crtc_cursor,
|
||||
&data,
|
||||
NULL);
|
||||
}
|
||||
|
||||
painted = painted || data.out_painted;
|
||||
}
|
||||
|
||||
priv->hw_state_invalidated = FALSE;
|
||||
@ -316,6 +393,55 @@ cursor_over_transformed_crtc (MetaCursorRenderer *renderer,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static float
|
||||
calculate_cursor_crtc_sprite_scale (MetaCursorSprite *cursor_sprite,
|
||||
MetaLogicalMonitor *logical_monitor)
|
||||
{
|
||||
return (meta_logical_monitor_get_scale (logical_monitor) *
|
||||
meta_cursor_sprite_get_texture_scale (cursor_sprite));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
can_draw_cursor_unscaled (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaBackend *backend;
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaRectangle cursor_rect;
|
||||
GList *logical_monitors;
|
||||
GList *l;
|
||||
gboolean has_visible_crtc_sprite = FALSE;
|
||||
|
||||
if (!meta_is_stage_views_scaled ())
|
||||
return meta_cursor_sprite_get_texture_scale (cursor_sprite) == 1.0;
|
||||
|
||||
backend = meta_get_backend ();
|
||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
||||
logical_monitors =
|
||||
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
||||
|
||||
if (!logical_monitors)
|
||||
return FALSE;
|
||||
|
||||
cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
|
||||
for (l = logical_monitors; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitor *logical_monitor = l->data;
|
||||
|
||||
if (!meta_rectangle_overlap (&cursor_rect, &logical_monitor->rect))
|
||||
continue;
|
||||
|
||||
if (calculate_cursor_crtc_sprite_scale (cursor_sprite,
|
||||
logical_monitor) != 1.0)
|
||||
return FALSE;
|
||||
|
||||
has_visible_crtc_sprite = TRUE;
|
||||
}
|
||||
|
||||
return has_visible_crtc_sprite;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_have_hw_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
@ -337,7 +463,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer,
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
if (meta_cursor_sprite_get_texture_scale (cursor_sprite) != 1)
|
||||
if (!can_draw_cursor_unscaled (renderer, cursor_sprite))
|
||||
return FALSE;
|
||||
|
||||
if (!has_valid_cursor_sprite_gbm_bo (cursor_sprite))
|
||||
|
@ -1937,6 +1937,11 @@ meta_monitor_manager_kms_get_capabilities (MetaMonitorManager *manager)
|
||||
MetaMonitorManagerCapability capabilities =
|
||||
META_MONITOR_MANAGER_CAPABILITY_NONE;
|
||||
|
||||
if (meta_backend_is_experimental_feature_enabled (
|
||||
backend,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
|
||||
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
|
||||
|
||||
switch (meta_renderer_native_get_mode (renderer_native))
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
@ -1967,6 +1972,20 @@ meta_monitor_manager_kms_get_max_screen_size (MetaMonitorManager *manager,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorLayoutMode
|
||||
meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
|
||||
{
|
||||
if (!meta_is_stage_views_enabled ())
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
|
||||
if (meta_backend_is_experimental_feature_enabled (
|
||||
meta_get_backend (),
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER))
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
||||
else
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_dispose (GObject *object)
|
||||
{
|
||||
@ -2011,4 +2030,5 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
|
||||
manager_class->get_supported_scales = meta_monitor_manager_kms_get_supported_scales;
|
||||
manager_class->get_capabilities = meta_monitor_manager_kms_get_capabilities;
|
||||
manager_class->get_max_screen_size = meta_monitor_manager_kms_get_max_screen_size;
|
||||
manager_class->get_default_layout_mode = meta_monitor_manager_kms_get_default_layout_mode;
|
||||
}
|
||||
|
@ -1707,16 +1707,26 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
MetaMonitorTransform view_transform;
|
||||
CoglOnscreen *onscreen = NULL;
|
||||
CoglOffscreen *offscreen = NULL;
|
||||
int scale;
|
||||
int width, height;
|
||||
MetaRendererView *view;
|
||||
GError *error = NULL;
|
||||
|
||||
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
scale = logical_monitor->scale;
|
||||
else
|
||||
scale = 1;
|
||||
|
||||
width = logical_monitor->rect.width * scale;
|
||||
height = logical_monitor->rect.height * scale;
|
||||
|
||||
onscreen = meta_renderer_native_create_onscreen (META_RENDERER_NATIVE (renderer),
|
||||
cogl_context,
|
||||
view_transform,
|
||||
logical_monitor->rect.width,
|
||||
logical_monitor->rect.height);
|
||||
width,
|
||||
height);
|
||||
if (!onscreen)
|
||||
meta_fatal ("Failed to allocate onscreen framebuffer\n");
|
||||
|
||||
@ -1725,14 +1735,15 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
offscreen = meta_renderer_native_create_offscreen (META_RENDERER_NATIVE (renderer),
|
||||
cogl_context,
|
||||
view_transform,
|
||||
logical_monitor->rect.width,
|
||||
logical_monitor->rect.height);
|
||||
width,
|
||||
height);
|
||||
if (!offscreen)
|
||||
meta_fatal ("Failed to allocate back buffer texture\n");
|
||||
}
|
||||
|
||||
view = g_object_new (META_TYPE_RENDERER_VIEW,
|
||||
"layout", &logical_monitor->rect,
|
||||
"scale", scale,
|
||||
"framebuffer", onscreen,
|
||||
"offscreen", offscreen,
|
||||
"logical-monitor", logical_monitor,
|
||||
|
@ -1623,6 +1623,16 @@ meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorLayoutMode
|
||||
meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager)
|
||||
{
|
||||
/*
|
||||
* Under X11, we still use the 'logical' layout mode, but it is
|
||||
* eqivalent to 'physical' as the scale is always 1.
|
||||
*/
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
||||
{
|
||||
@ -1703,6 +1713,7 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
|
||||
manager_class->get_supported_scales = meta_monitor_manager_xrandr_get_supported_scales;
|
||||
manager_class->get_capabilities = meta_monitor_manager_xrandr_get_capabilities;
|
||||
manager_class->get_max_screen_size = meta_monitor_manager_xrandr_get_max_screen_size;
|
||||
manager_class->get_default_layout_mode = meta_monitor_manager_xrandr_get_default_layout_mode;
|
||||
|
||||
quark_meta_monitor_xrandr_data =
|
||||
g_quark_from_static_string ("-meta-monitor-xrandr-data");
|
||||
|
@ -122,6 +122,7 @@ meta_renderer_x11_create_view (MetaRenderer *renderer,
|
||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
MetaMonitorTransform view_transform;
|
||||
int view_scale;
|
||||
int width, height;
|
||||
CoglTexture2D *texture_2d;
|
||||
CoglOffscreen *fake_onscreen;
|
||||
@ -130,11 +131,16 @@ meta_renderer_x11_create_view (MetaRenderer *renderer,
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
width = logical_monitor->rect.width;
|
||||
height = logical_monitor->rect.height;
|
||||
|
||||
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
view_scale = logical_monitor->scale;
|
||||
else
|
||||
view_scale = 1;
|
||||
|
||||
width = logical_monitor->rect.width * view_scale;
|
||||
height = logical_monitor->rect.height * view_scale;
|
||||
|
||||
texture_2d = cogl_texture_2d_new_with_size (cogl_context, width, height);
|
||||
fake_onscreen = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture_2d));
|
||||
|
||||
@ -158,6 +164,7 @@ meta_renderer_x11_create_view (MetaRenderer *renderer,
|
||||
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
|
||||
"offscreen", COGL_FRAMEBUFFER (offscreen),
|
||||
"transform", view_transform,
|
||||
"scale", view_scale,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "compositor/region-utils.h"
|
||||
|
||||
enum {
|
||||
@ -104,9 +105,12 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *self)
|
||||
|
||||
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
|
||||
/* XXX: We do not handle x11 clients yet */
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (window);
|
||||
if (!meta_is_stage_views_scaled ())
|
||||
{
|
||||
/* XXX: We do not handle x11 clients yet */
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (window);
|
||||
}
|
||||
|
||||
return (double) geometry_scale / (double) surface->scale;
|
||||
}
|
||||
|
@ -1279,6 +1279,37 @@ update_num_workspaces (MetaScreen *screen,
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
static int
|
||||
find_highest_logical_monitor_scale (MetaBackend *backend,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaCursorRenderer *cursor_renderer =
|
||||
meta_backend_get_cursor_renderer (backend);
|
||||
MetaRectangle cursor_rect;
|
||||
GList *logical_monitors;
|
||||
GList *l;
|
||||
int highest_scale = 0.0;
|
||||
|
||||
cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
|
||||
cursor_sprite);
|
||||
|
||||
logical_monitors =
|
||||
meta_monitor_manager_get_logical_monitors (monitor_manager);
|
||||
for (l = logical_monitors; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitor *logical_monitor = l->data;
|
||||
|
||||
if (!meta_rectangle_overlap (&cursor_rect, &logical_monitor->rect))
|
||||
continue;
|
||||
|
||||
highest_scale = MAX (highest_scale, logical_monitor->scale);
|
||||
}
|
||||
|
||||
return highest_scale;
|
||||
}
|
||||
|
||||
static void
|
||||
root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
int x,
|
||||
@ -1286,16 +1317,35 @@ root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
logical_monitor =
|
||||
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
|
||||
if (meta_is_stage_views_scaled ())
|
||||
{
|
||||
int scale;
|
||||
|
||||
/* Reload the cursor texture if the scale has changed. */
|
||||
if (logical_monitor)
|
||||
meta_cursor_sprite_set_theme_scale (cursor_sprite, logical_monitor->scale);
|
||||
scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
|
||||
if (scale != 0.0)
|
||||
{
|
||||
meta_cursor_sprite_set_theme_scale (cursor_sprite, scale);
|
||||
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
|
||||
logical_monitor =
|
||||
meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
|
||||
|
||||
/* Reload the cursor texture if the scale has changed. */
|
||||
if (logical_monitor)
|
||||
{
|
||||
meta_cursor_sprite_set_theme_scale (cursor_sprite,
|
||||
logical_monitor->scale);
|
||||
meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2206,6 +2256,9 @@ static void
|
||||
on_monitors_changed (MetaMonitorManager *manager,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
MetaBackend *backend;
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
|
||||
meta_monitor_manager_get_screen_size (manager,
|
||||
&screen->rect.width,
|
||||
&screen->rect.height);
|
||||
@ -2237,6 +2290,10 @@ on_monitors_changed (MetaMonitorManager *manager,
|
||||
|
||||
meta_screen_queue_check_fullscreen (screen);
|
||||
|
||||
backend = meta_get_backend ();
|
||||
cursor_renderer = meta_backend_get_cursor_renderer (backend);
|
||||
meta_cursor_renderer_force_update (cursor_renderer);
|
||||
|
||||
g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0);
|
||||
}
|
||||
|
||||
|
@ -344,10 +344,34 @@
|
||||
scale factors of logical monitors supported by the display server.
|
||||
|
||||
|
||||
@layout_mode current layout mode represents the way logical monitors
|
||||
are layed out on the screen. Possible modes include:
|
||||
|
||||
1 : physical
|
||||
2 : logical
|
||||
|
||||
With physical layout mode, each logical monitor has the same dimensions
|
||||
an the monitor modes of the associated monitors assigned to it, no
|
||||
matter what scale is in use.
|
||||
|
||||
With logical mode, the dimension of a logical monitor is the dimension
|
||||
of the monitor mode, divided by the logical monitor scale.
|
||||
|
||||
|
||||
Possible @properties are:
|
||||
|
||||
* "supports-mirroring" (b): FALSE if mirroring not supported; TRUE or not
|
||||
present if mirroring is supported.
|
||||
* "layout-mode" (u): Represents in what way logical monitors are laid
|
||||
out on the screen. The layout mode can be either
|
||||
of the ones listed below. Absence of this property
|
||||
means the layout mode cannot be changed, and that
|
||||
"logical" mode is assumed to be used.
|
||||
* 1 : logical - the dimension of a logical monitor is derived from
|
||||
the monitor modes associated with it, then scaled
|
||||
using the logical monitor scale.
|
||||
* 2 : physical - the dimension of a logical monitor is derived from
|
||||
the monitor modes associated with it.
|
||||
-->
|
||||
<method name="GetCurrentState">
|
||||
<arg name="serial" direction="out" type="u" />
|
||||
@ -386,6 +410,13 @@
|
||||
- "enable_underscanning" (b): enable monitor underscanning;
|
||||
may only be set when underscanning
|
||||
is supported (see GetCurrentState).
|
||||
|
||||
@properties may effect the global monitor configuration state. Possible
|
||||
properties are:
|
||||
|
||||
* "layout-mode" (u): layout mode the passed configuration is in; may
|
||||
only be set when changing the layout mode is
|
||||
supported (see GetCurrentState).
|
||||
-->
|
||||
<method name="ApplyMonitorsConfig">
|
||||
<arg name="serial" direction="in" type="u" />
|
||||
|
@ -380,10 +380,28 @@ meta_monitor_manager_test_get_supported_scales (MetaMonitorManager *manager,
|
||||
*n_scales = G_N_ELEMENTS (supported_scales_test);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_monitor_framebuffer_scaled (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
return meta_backend_is_experimental_feature_enabled (
|
||||
backend,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
|
||||
}
|
||||
|
||||
static MetaMonitorManagerCapability
|
||||
meta_monitor_manager_test_get_capabilities (MetaMonitorManager *manager)
|
||||
{
|
||||
return META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
|
||||
MetaMonitorManagerCapability capabilities =
|
||||
META_MONITOR_MANAGER_CAPABILITY_NONE;
|
||||
|
||||
capabilities |= META_MONITOR_MANAGER_CAPABILITY_MIRRORING;
|
||||
|
||||
if (is_monitor_framebuffer_scaled ())
|
||||
capabilities |= META_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE;
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -400,6 +418,18 @@ meta_monitor_manager_test_get_max_screen_size (MetaMonitorManager *manager,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaLogicalMonitorLayoutMode
|
||||
meta_monitor_manager_test_get_default_layout_mode (MetaMonitorManager *manager)
|
||||
{
|
||||
if (!meta_is_stage_views_enabled ())
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
|
||||
if (is_monitor_framebuffer_scaled ())
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_LOGICAL;
|
||||
else
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_test_dispose (GObject *object)
|
||||
{
|
||||
@ -436,4 +466,5 @@ meta_monitor_manager_test_class_init (MetaMonitorManagerTestClass *klass)
|
||||
manager_class->get_supported_scales = meta_monitor_manager_test_get_supported_scales;
|
||||
manager_class->get_capabilities = meta_monitor_manager_test_get_capabilities;
|
||||
manager_class->get_max_screen_size = meta_monitor_manager_test_get_max_screen_size;
|
||||
manager_class->get_default_layout_mode = meta_monitor_manager_test_get_default_layout_mode;
|
||||
}
|
||||
|
@ -472,8 +472,8 @@ meta_test_monitor_store_scale (void)
|
||||
.layout = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = 1920,
|
||||
.height = 1080
|
||||
.width = 960,
|
||||
.height = 540
|
||||
},
|
||||
.scale = 2,
|
||||
.is_primary = TRUE,
|
||||
|
@ -1354,13 +1354,13 @@ meta_test_monitor_hidpi_linear_config (void)
|
||||
{
|
||||
.monitors = { 0 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 0, .y = 0, .width = 1280, .height = 720 },
|
||||
.layout = { .x = 0, .y = 0, .width = 640, .height = 360 },
|
||||
.scale = 2
|
||||
},
|
||||
{
|
||||
.monitors = { 1 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 1280, .y = 0, .width = 1024, .height = 768 },
|
||||
.layout = { .x = 640, .y = 0, .width = 1024, .height = 768 },
|
||||
.scale = 1
|
||||
}
|
||||
},
|
||||
@ -1376,12 +1376,18 @@ meta_test_monitor_hidpi_linear_config (void)
|
||||
}
|
||||
},
|
||||
.n_crtcs = 2,
|
||||
.screen_width = 1280 + 1024,
|
||||
.screen_width = 640 + 1024,
|
||||
.screen_height = 768
|
||||
}
|
||||
};
|
||||
MetaMonitorTestSetup *test_setup;
|
||||
|
||||
if (!is_using_monitor_config_manager ())
|
||||
{
|
||||
g_test_skip ("Not using MetaMonitorConfigManager");
|
||||
return;
|
||||
}
|
||||
|
||||
test_setup = create_monitor_test_setup (&test_case,
|
||||
MONITOR_TEST_FLAG_NO_STORED);
|
||||
emulate_hotplug (test_setup);
|
||||
@ -2689,7 +2695,7 @@ meta_test_monitor_custom_scale_config (void)
|
||||
{
|
||||
.monitors = { 0 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 0, .y = 0, .width = 1920, .height = 1080 },
|
||||
.layout = { .x = 0, .y = 0, .width = 960, .height = 540 },
|
||||
.scale = 2
|
||||
}
|
||||
},
|
||||
@ -2703,8 +2709,8 @@ meta_test_monitor_custom_scale_config (void)
|
||||
},
|
||||
.n_crtcs = 1,
|
||||
.n_tiled_monitors = 0,
|
||||
.screen_width = 1920,
|
||||
.screen_height = 1080
|
||||
.screen_width = 960,
|
||||
.screen_height = 540
|
||||
}
|
||||
};
|
||||
MetaMonitorTestSetup *test_setup;
|
||||
@ -2824,7 +2830,7 @@ meta_test_monitor_custom_tiled_config (void)
|
||||
{
|
||||
.monitors = { 0 },
|
||||
.n_monitors = 1,
|
||||
.layout = { .x = 0, .y = 0, .width = 800, .height = 600 },
|
||||
.layout = { .x = 0, .y = 0, .width = 400, .height = 300 },
|
||||
.scale = 2
|
||||
}
|
||||
},
|
||||
@ -2841,8 +2847,8 @@ meta_test_monitor_custom_tiled_config (void)
|
||||
},
|
||||
.n_crtcs = 2,
|
||||
.n_tiled_monitors = 1,
|
||||
.screen_width = 800,
|
||||
.screen_height = 600
|
||||
.screen_width = 400,
|
||||
.screen_height = 300
|
||||
}
|
||||
};
|
||||
MetaMonitorTestSetup *test_setup;
|
||||
|
@ -214,8 +214,15 @@ meta_test_adjecent_to (void)
|
||||
static gboolean
|
||||
run_tests (gpointer data)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
gboolean ret;
|
||||
|
||||
meta_backend_override_experimental_features (backend);
|
||||
|
||||
meta_backend_enable_experimental_feature (
|
||||
backend,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER);
|
||||
|
||||
ret = g_test_run ();
|
||||
|
||||
meta_quit (ret != 0);
|
||||
|
@ -112,7 +112,11 @@ cursor_sprite_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
{
|
||||
float texture_scale;
|
||||
|
||||
texture_scale = (float) logical_monitor->scale / surface->scale;
|
||||
if (meta_is_stage_views_scaled ())
|
||||
texture_scale = 1.0 / surface->scale;
|
||||
else
|
||||
texture_scale = (float) logical_monitor->scale / surface->scale;
|
||||
|
||||
meta_cursor_sprite_set_texture_scale (cursor_sprite, texture_scale);
|
||||
}
|
||||
}
|
||||
|
@ -38,11 +38,14 @@
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "backends/meta-backend-private.h"
|
||||
|
||||
struct _MetaWindowWayland
|
||||
{
|
||||
MetaWindow parent;
|
||||
|
||||
int geometry_scale;
|
||||
|
||||
MetaWaylandSerial pending_configure_serial;
|
||||
gboolean has_pending_move;
|
||||
int pending_move_x;
|
||||
@ -61,11 +64,24 @@ struct _MetaWindowWaylandClass
|
||||
|
||||
G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW)
|
||||
|
||||
static int
|
||||
get_window_geometry_scale_for_logical_monitor (MetaLogicalMonitor *logical_monitor)
|
||||
{
|
||||
if (meta_is_stage_views_scaled ())
|
||||
return 1;
|
||||
else
|
||||
return logical_monitor->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_wayland_manage (MetaWindow *window)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
MetaDisplay *display = window->display;
|
||||
|
||||
wl_window->geometry_scale =
|
||||
get_window_geometry_scale_for_logical_monitor (window->monitor);
|
||||
|
||||
meta_display_register_wayland_window (display, window);
|
||||
|
||||
{
|
||||
@ -375,6 +391,12 @@ meta_window_wayland_update_main_monitor (MetaWindow *window)
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
{
|
||||
window->monitor = to;
|
||||
return;
|
||||
}
|
||||
|
||||
/* To avoid a window alternating between two main monitors because scaling
|
||||
* changes the main monitor, wait until both the current and the new scale
|
||||
* will result in the same main monitor. */
|
||||
@ -393,16 +415,24 @@ static void
|
||||
meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
||||
const MetaLogicalMonitor *old)
|
||||
{
|
||||
MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
|
||||
int old_geometry_scale = wl_window->geometry_scale;
|
||||
int geometry_scale;
|
||||
float scale_factor;
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
if (!window->monitor)
|
||||
return;
|
||||
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (window);
|
||||
|
||||
/* This function makes sure that window geometry, window actor geometry and
|
||||
* surface actor geometry gets set according the old and current main monitor
|
||||
* scale. If there either is no past or current main monitor, or if the scale
|
||||
* didn't change, there is nothing to do. */
|
||||
if (old == NULL ||
|
||||
window->monitor == NULL ||
|
||||
old->scale == window->monitor->scale)
|
||||
old_geometry_scale == geometry_scale)
|
||||
return;
|
||||
|
||||
/* MetaWindow keeps its rectangles in the physical pixel coordinate space.
|
||||
@ -410,7 +440,7 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
||||
* window surfaces to be scaled given the monitor scale, so we need to scale
|
||||
* the rectangles in MetaWindow accordingly. */
|
||||
|
||||
scale_factor = (float)window->monitor->scale / old->scale;
|
||||
scale_factor = (float) geometry_scale / old_geometry_scale;
|
||||
|
||||
/* Window size. */
|
||||
scale_rect_size (&window->rect, scale_factor);
|
||||
@ -419,7 +449,6 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
||||
scale_size (&window->size_hints.min_width, &window->size_hints.min_height, scale_factor);
|
||||
scale_size (&window->size_hints.max_width, &window->size_hints.max_height, scale_factor);
|
||||
|
||||
|
||||
/* Window geometry offset (XXX: Need a better place, see
|
||||
* meta_window_wayland_move_resize). */
|
||||
window->custom_frame_extents.left =
|
||||
@ -449,6 +478,8 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
||||
meta_surface_actor_wayland_sync_state_recursive (actor);
|
||||
}
|
||||
|
||||
wl_window->geometry_scale = geometry_scale;
|
||||
|
||||
meta_window_emit_size_changed (window);
|
||||
}
|
||||
|
||||
@ -477,6 +508,8 @@ meta_window_wayland_init (MetaWindowWayland *wl_window)
|
||||
{
|
||||
MetaWindow *window = META_WINDOW (wl_window);
|
||||
|
||||
wl_window->geometry_scale = 1;
|
||||
|
||||
g_signal_connect (window, "notify::appears-focused",
|
||||
G_CALLBACK (appears_focused_changed), NULL);
|
||||
}
|
||||
@ -571,7 +604,7 @@ should_do_pending_move (MetaWindowWayland *wl_window,
|
||||
int
|
||||
meta_window_wayland_get_geometry_scale (MetaWindow *window)
|
||||
{
|
||||
return window->monitor->scale;
|
||||
return get_window_geometry_scale_for_logical_monitor (window->monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user