xrandr: use "hotplug_mode_update" property
Use the "hotplug_mode_update" connector property indicating that the screen settings should be updated: get a new preferred mode on hotplug events to handle dynamic guest resizing (where you resize the host window and the guest resizes with it). https://bugzilla.gnome.org/show_bug.cgi?id=711216
This commit is contained in:
parent
21c46852cd
commit
ca5d115715
@ -817,6 +817,22 @@ meta_monitor_config_match_current (MetaMonitorConfig *self,
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
|
||||||
|
{
|
||||||
|
MetaOutput *outputs;
|
||||||
|
unsigned n_outputs;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
|
||||||
|
|
||||||
|
for (i = 0; i < n_outputs; i++)
|
||||||
|
if (outputs[i].hotplug_mode_update)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static MetaConfiguration *
|
static MetaConfiguration *
|
||||||
meta_monitor_config_get_stored (MetaMonitorConfig *self,
|
meta_monitor_config_get_stored (MetaMonitorConfig *self,
|
||||||
MetaOutput *outputs,
|
MetaOutput *outputs,
|
||||||
|
@ -116,6 +116,9 @@ struct _MetaOutput
|
|||||||
*/
|
*/
|
||||||
gboolean is_primary;
|
gboolean is_primary;
|
||||||
gboolean is_presentation;
|
gboolean is_presentation;
|
||||||
|
|
||||||
|
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
|
||||||
|
gboolean hotplug_mode_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaCRTC
|
struct _MetaCRTC
|
||||||
@ -383,6 +386,7 @@ void meta_output_info_free (MetaOutputInfo *info);
|
|||||||
|
|
||||||
void meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
void meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||||
int n_old_outputs);
|
int n_old_outputs);
|
||||||
|
gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
|
||||||
|
|
||||||
/* Returns true if transform causes width and height to be inverted
|
/* Returns true if transform causes width and height to be inverted
|
||||||
This is true for the odd transforms in the enum */
|
This is true for the odd transforms in the enum */
|
||||||
|
@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||||
|
XID output_id)
|
||||||
|
{
|
||||||
|
MetaDisplay *display = meta_get_display ();
|
||||||
|
XRRPropertyInfo *info;
|
||||||
|
gboolean result = FALSE;
|
||||||
|
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
|
||||||
|
display->atom_hotplug_mode_update);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
result = TRUE;
|
||||||
|
XFree (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
@ -484,6 +507,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
|||||||
meta_output->width_mm = output->mm_width;
|
meta_output->width_mm = output->mm_width;
|
||||||
meta_output->height_mm = output->mm_height;
|
meta_output->height_mm = output->mm_height;
|
||||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||||
|
meta_output->hotplug_mode_update =
|
||||||
|
output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
|
||||||
|
|
||||||
meta_output->n_modes = output->nmode;
|
meta_output->n_modes = output->nmode;
|
||||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||||
@ -971,6 +996,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
|
|||||||
XRRFreeGamma (gamma);
|
XRRFreeGamma (gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager)
|
||||||
|
{
|
||||||
|
/* This will be a no-op if the change was from our side, as
|
||||||
|
we already called it in the DBus method handler */
|
||||||
|
meta_monitor_config_update_current (manager->config, manager);
|
||||||
|
|
||||||
|
meta_monitor_manager_rebuild_derived (manager);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
||||||
XEvent *event)
|
XEvent *event)
|
||||||
@ -980,6 +1015,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
|||||||
MetaCRTC *old_crtcs;
|
MetaCRTC *old_crtcs;
|
||||||
MetaMonitorMode *old_modes;
|
MetaMonitorMode *old_modes;
|
||||||
int n_old_outputs;
|
int n_old_outputs;
|
||||||
|
gboolean new_config;
|
||||||
|
|
||||||
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -995,31 +1031,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
|||||||
manager->serial++;
|
manager->serial++;
|
||||||
meta_monitor_manager_xrandr_read_current (manager);
|
meta_monitor_manager_xrandr_read_current (manager);
|
||||||
|
|
||||||
/* Check if the current intended configuration has the same outputs
|
new_config = manager_xrandr->resources->timestamp >=
|
||||||
as the new real one, or if the event is a result of an XRandR call.
|
manager_xrandr->resources->configTimestamp;
|
||||||
If so, we can go straight to rebuild the logical config and tell
|
if (meta_monitor_manager_has_hotplug_mode_update (manager))
|
||||||
the outside world.
|
|
||||||
Otherwise, this event was caused by hotplug, so give a chance to
|
|
||||||
MetaMonitorConfig.
|
|
||||||
|
|
||||||
Note that we need to check both the timestamps and the list of
|
|
||||||
outputs, because the X server might emit spurious events with
|
|
||||||
new configTimestamps (bug 702804), and the driver may have
|
|
||||||
changed the EDID for some other reason (old broken qxl and vbox
|
|
||||||
drivers...).
|
|
||||||
*/
|
|
||||||
if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp ||
|
|
||||||
meta_monitor_config_match_current (manager->config, manager))
|
|
||||||
{
|
{
|
||||||
/* This will be a no-op if the change was from our side, as
|
/* Check if the current intended configuration is a result of an
|
||||||
we already called it in the DBus method handler */
|
XRandR call. Otherwise, hotplug_mode_update tells us to get
|
||||||
meta_monitor_config_update_current (manager->config, manager);
|
a new preferred mode on hotplug events to handle dynamic
|
||||||
|
guest resizing. */
|
||||||
meta_monitor_manager_rebuild_derived (manager);
|
if (new_config)
|
||||||
|
meta_monitor_manager_xrandr_rebuild_derived (manager);
|
||||||
|
else
|
||||||
|
meta_monitor_config_make_default (manager->config, manager);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!meta_monitor_config_apply_stored (manager->config, manager))
|
/* Check if the current intended configuration has the same outputs
|
||||||
|
as the new real one, or if the event is a result of an XRandR call.
|
||||||
|
If so, we can go straight to rebuild the logical config and tell
|
||||||
|
the outside world.
|
||||||
|
Otherwise, this event was caused by hotplug, so give a chance to
|
||||||
|
MetaMonitorConfig.
|
||||||
|
|
||||||
|
Note that we need to check both the timestamps and the list of
|
||||||
|
outputs, because the X server might emit spurious events with new
|
||||||
|
configTimestamps (bug 702804), and the driver may have changed
|
||||||
|
the EDID for some other reason (old qxl and vbox drivers). */
|
||||||
|
if (new_config || meta_monitor_config_match_current (manager->config, manager))
|
||||||
|
meta_monitor_manager_xrandr_rebuild_derived (manager);
|
||||||
|
else if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||||
meta_monitor_config_make_default (manager->config, manager);
|
meta_monitor_config_make_default (manager->config, manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ item(TIMESTAMP)
|
|||||||
item(VERSION)
|
item(VERSION)
|
||||||
item(ATOM_PAIR)
|
item(ATOM_PAIR)
|
||||||
item(BACKLIGHT)
|
item(BACKLIGHT)
|
||||||
|
item(hotplug_mode_update)
|
||||||
|
|
||||||
/* Oddities: These are used, and we need atoms for them,
|
/* Oddities: These are used, and we need atoms for them,
|
||||||
* but when we need all _NET_WM hints (i.e. when we're making
|
* but when we need all _NET_WM hints (i.e. when we're making
|
||||||
|
Loading…
Reference in New Issue
Block a user