display-config: Add size constraints and (global) scaled mode checks

Make possible to set scaled size constraints per configuration, and add a method
to verify if the current mode at scale is allowed for such config.

This allows to perform such check also in case we have global scaling enabled,
as in such case we must verify that all the selected current modes are supported
by the given scale.

Fixes GNOME/mutter#407
This commit is contained in:
Marco Trevisan (Treviño) 2018-11-30 11:40:06 -05:00 committed by Robert Ancell
parent 04f3264c6a
commit 9ef001b3b1
3 changed files with 93 additions and 0 deletions

View file

@ -878,6 +878,9 @@ struct _CcDisplayConfigDBus
GVariant *state;
GDBusConnection *connection;
int min_width;
int min_height;
guint32 serial;
gboolean supports_mirroring;
gboolean supports_changing_layout_mode;
@ -1200,6 +1203,66 @@ cc_display_config_dbus_is_layout_logical (CcDisplayConfig *pself)
return self->layout_mode == CC_DISPLAY_LAYOUT_MODE_LOGICAL;
}
static gboolean
is_scaled_mode_allowed (CcDisplayConfigDBus *self,
CcDisplayMode *pmode,
double scale)
{
CcDisplayModeDBus *mode = CC_DISPLAY_MODE_DBUS (pmode);
if (!cc_display_mode_dbus_is_supported_scale (pmode, scale))
return FALSE;
return (round (mode->width / scale) >= self->min_width &&
round (mode->height / scale) >= self->min_height);
}
static gboolean
is_scale_allowed_by_active_monitors (CcDisplayConfigDBus *self,
double scale)
{
GList *l;
for (l = self->monitors; l != NULL; l = l->next)
{
CcDisplayMonitorDBus *m = CC_DISPLAY_MONITOR_DBUS (l->data);
if (!cc_display_monitor_is_active (CC_DISPLAY_MONITOR (m)))
continue;
if (!is_scaled_mode_allowed (self, m->current_mode, scale))
return FALSE;
}
return TRUE;
}
static void
cc_display_config_dbus_set_minimum_size (CcDisplayConfig *pself,
int width,
int height)
{
CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself);
g_assert (width >= 0 && height >= 0);
self->min_width = width;
self->min_height = height;
}
static gboolean
cc_display_config_dbus_is_scaled_mode_valid (CcDisplayConfig *pself,
CcDisplayMode *mode,
double scale)
{
CcDisplayConfigDBus *self = CC_DISPLAY_CONFIG_DBUS (pself);
if (self->global_scale_required)
return is_scale_allowed_by_active_monitors (self, scale);
return is_scaled_mode_allowed (self, mode, scale);
}
static void
cc_display_config_dbus_init (CcDisplayConfigDBus *self)
{
@ -1481,6 +1544,8 @@ cc_display_config_dbus_class_init (CcDisplayConfigDBusClass *klass)
parent_class->set_cloning = cc_display_config_dbus_set_cloning;
parent_class->get_cloning_modes = cc_display_config_dbus_get_cloning_modes;
parent_class->is_layout_logical = cc_display_config_dbus_is_layout_logical;
parent_class->is_scaled_mode_valid = cc_display_config_dbus_is_scaled_mode_valid;
parent_class->set_minimum_size = cc_display_config_dbus_set_minimum_size;
pspec = g_param_spec_variant ("state",
"GVariant",