Reverse handling of XRandR events between Screen and MonitorManager
Now MonitorManager does its own handling of XRandR events, which means we no longer handle ConfigureNotify on the root window. MetaScreen reacts to MonitorManager::monitor-changed and updates its internal state, including the new size. This paves the way for doing display configuration using only the dummy backend, which would allow testing wl_output interfaces. https://bugzilla.gnome.org/show_bug.cgi?id=705670
This commit is contained in:
parent
57d083730e
commit
bf40409d97
@ -2146,6 +2146,7 @@ event_callback (XEvent *event,
|
||||
gboolean bypass_compositor;
|
||||
gboolean filter_out_event;
|
||||
XIEvent *input_event;
|
||||
MetaMonitorManager *monitor;
|
||||
|
||||
display = data;
|
||||
|
||||
@ -2157,6 +2158,14 @@ event_callback (XEvent *event,
|
||||
#ifdef HAVE_STARTUP_NOTIFICATION
|
||||
sn_display_process_event (display->sn_display, event);
|
||||
#endif
|
||||
|
||||
/* Intercept XRandR events early and don't attempt any
|
||||
processing for them. We still let them through to Gdk though,
|
||||
so it can update its own internal state.
|
||||
*/
|
||||
monitor = meta_monitor_manager_get ();
|
||||
if (meta_monitor_manager_handle_xevent (monitor, event))
|
||||
return FALSE;
|
||||
|
||||
bypass_compositor = FALSE;
|
||||
filter_out_event = FALSE;
|
||||
@ -2822,32 +2831,10 @@ event_callback (XEvent *event,
|
||||
meta_stack_tracker_configure_event (screen->stack_tracker,
|
||||
&event->xconfigure);
|
||||
}
|
||||
|
||||
if (window && window->override_redirect)
|
||||
meta_window_configure_notify (window, &event->xconfigure);
|
||||
else
|
||||
/* Handle screen resize */
|
||||
{
|
||||
MetaScreen *screen;
|
||||
|
||||
screen = meta_display_screen_for_root (display,
|
||||
event->xconfigure.window);
|
||||
|
||||
if (screen != NULL)
|
||||
{
|
||||
#ifdef HAVE_RANDR
|
||||
/* do the resize the official way */
|
||||
XRRUpdateConfiguration (event);
|
||||
#else
|
||||
/* poke around in Xlib */
|
||||
screen->xscreen->width = event->xconfigure.width;
|
||||
screen->xscreen->height = event->xconfigure.height;
|
||||
#endif
|
||||
|
||||
meta_screen_resize (screen,
|
||||
event->xconfigure.width,
|
||||
event->xconfigure.height);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
/* This comment and code is found in both twm and fvwm */
|
||||
|
@ -162,6 +162,11 @@ MetaOutput *meta_monitor_manager_get_outputs (MetaMonitorManager *
|
||||
|
||||
int meta_monitor_manager_get_primary_index (MetaMonitorManager *manager);
|
||||
|
||||
void meta_monitor_manager_invalidate (MetaMonitorManager *manager);
|
||||
gboolean meta_monitor_manager_handle_xevent (MetaMonitorManager *manager,
|
||||
XEvent *event);
|
||||
|
||||
void meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
|
||||
int *width,
|
||||
int *height);
|
||||
|
||||
#endif
|
||||
|
@ -56,16 +56,16 @@ enum wl_output_transform {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
META_BACKEND_UNSPECIFIED,
|
||||
META_BACKEND_DUMMY,
|
||||
META_BACKEND_XRANDR,
|
||||
META_BACKEND_COGL
|
||||
} MetaBackend;
|
||||
META_BACKEND_XRANDR
|
||||
} MetaMonitorBackend;
|
||||
|
||||
struct _MetaMonitorManager
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
MetaBackend backend;
|
||||
MetaMonitorBackend backend;
|
||||
|
||||
/* XXX: this structure is very badly
|
||||
packed, but I like the logical organization
|
||||
@ -75,6 +75,8 @@ struct _MetaMonitorManager
|
||||
|
||||
int max_screen_width;
|
||||
int max_screen_height;
|
||||
int screen_width;
|
||||
int screen_height;
|
||||
|
||||
/* Outputs refer to physical screens,
|
||||
CRTCs refer to stuff that can drive outputs
|
||||
@ -100,6 +102,8 @@ struct _MetaMonitorManager
|
||||
Display *xdisplay;
|
||||
XRRScreenResources *resources;
|
||||
int time;
|
||||
int rr_event_base;
|
||||
int rr_error_base;
|
||||
#endif
|
||||
|
||||
int dbus_name_id;
|
||||
@ -125,23 +129,17 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
|
||||
{
|
||||
manager->backend = META_BACKEND_DUMMY;
|
||||
|
||||
manager->max_screen_width = 65535;
|
||||
manager->max_screen_height = 65535;
|
||||
manager->screen_width = 1024;
|
||||
manager->screen_height = 768;
|
||||
|
||||
manager->modes = g_new0 (MetaMonitorMode, 1);
|
||||
manager->n_modes = 1;
|
||||
|
||||
manager->modes[0].mode_id = 1;
|
||||
if (manager->xdisplay)
|
||||
{
|
||||
Screen *screen = ScreenOfDisplay (manager->xdisplay,
|
||||
DefaultScreen (manager->xdisplay));
|
||||
|
||||
manager->modes[0].width = WidthOfScreen (screen);
|
||||
manager->modes[0].height = HeightOfScreen (screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
manager->modes[0].width = 1024;
|
||||
manager->modes[0].height = 768;
|
||||
}
|
||||
manager->modes[0].width = manager->screen_width;
|
||||
manager->modes[0].height = manager->screen_height;
|
||||
manager->modes[0].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs = g_new0 (MetaCRTC, 1);
|
||||
@ -177,9 +175,6 @@ make_dummy_monitor_config (MetaMonitorManager *manager)
|
||||
manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[0].n_possible_clones = 0;
|
||||
manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
|
||||
manager->max_screen_width = manager->modes[0].width;
|
||||
manager->max_screen_height = manager->modes[0].height;
|
||||
}
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
@ -192,6 +187,7 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
|
||||
unsigned int i, j, k;
|
||||
unsigned int n_actual_outputs;
|
||||
int min_width, min_height;
|
||||
Screen *screen;
|
||||
|
||||
if (manager->resources)
|
||||
XRRFreeScreenResources (manager->resources);
|
||||
@ -203,12 +199,17 @@ read_monitor_infos_from_xrandr (MetaMonitorManager *manager)
|
||||
&manager->max_screen_width,
|
||||
&manager->max_screen_height);
|
||||
|
||||
screen = ScreenOfDisplay (manager->xdisplay,
|
||||
DefaultScreen (manager->xdisplay));
|
||||
/* This is updated because we called RRUpdateConfiguration below */
|
||||
manager->screen_width = WidthOfScreen (screen);
|
||||
manager->screen_height = HeightOfScreen (screen);
|
||||
|
||||
resources = XRRGetScreenResourcesCurrent (manager->xdisplay,
|
||||
DefaultRootWindow (manager->xdisplay));
|
||||
if (!resources)
|
||||
return make_dummy_monitor_config (manager);
|
||||
|
||||
manager->backend = META_BACKEND_XRANDR;
|
||||
manager->resources = resources;
|
||||
manager->time = resources->configTimestamp;
|
||||
manager->n_outputs = resources->noutput;
|
||||
@ -388,7 +389,7 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static MetaMonitorBackend
|
||||
make_debug_config (MetaMonitorManager *manager)
|
||||
{
|
||||
const char *env;
|
||||
@ -396,14 +397,14 @@ make_debug_config (MetaMonitorManager *manager)
|
||||
env = g_getenv ("META_DEBUG_MULTIMONITOR");
|
||||
|
||||
if (env == NULL)
|
||||
return FALSE;
|
||||
return META_BACKEND_UNSPECIFIED;
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
if (strcmp (env, "xrandr") == 0)
|
||||
read_monitor_infos_from_xrandr (manager);
|
||||
return META_BACKEND_XRANDR;
|
||||
else
|
||||
#endif
|
||||
make_dummy_monitor_config (manager);
|
||||
return META_BACKEND_DUMMY;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -411,15 +412,12 @@ make_debug_config (MetaMonitorManager *manager)
|
||||
static void
|
||||
read_current_config (MetaMonitorManager *manager)
|
||||
{
|
||||
if (make_debug_config (manager))
|
||||
return;
|
||||
|
||||
if (has_dummy_output ())
|
||||
return make_dummy_monitor_config (manager);
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
return read_monitor_infos_from_xrandr (manager);
|
||||
if (manager->backend == META_BACKEND_XRANDR)
|
||||
return read_monitor_infos_from_xrandr (manager);
|
||||
#endif
|
||||
|
||||
return make_dummy_monitor_config (manager);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -526,6 +524,40 @@ meta_monitor_manager_new (Display *display)
|
||||
|
||||
manager->xdisplay = display;
|
||||
|
||||
manager->backend = make_debug_config (manager);
|
||||
|
||||
if (manager->backend == META_BACKEND_UNSPECIFIED)
|
||||
{
|
||||
#ifdef HAVE_XRANDR
|
||||
if (display)
|
||||
manager->backend = META_BACKEND_XRANDR;
|
||||
else
|
||||
#endif
|
||||
if (has_dummy_output ())
|
||||
manager->backend = META_BACKEND_DUMMY;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XRANDR
|
||||
if (manager->backend == META_BACKEND_XRANDR)
|
||||
{
|
||||
if (!XRRQueryExtension (display,
|
||||
&manager->rr_event_base,
|
||||
&manager->rr_error_base))
|
||||
{
|
||||
manager->backend = META_BACKEND_DUMMY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We only use ScreenChangeNotify, but GDK uses the others,
|
||||
and we don't want to step on its toes */
|
||||
XRRSelectInput (display, DefaultRootWindow (display),
|
||||
RRScreenChangeNotifyMask
|
||||
| RRCrtcChangeNotifyMask
|
||||
| RROutputPropertyNotifyMask);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
read_current_config (manager);
|
||||
make_logical_config (manager);
|
||||
return manager;
|
||||
@ -1157,7 +1189,17 @@ meta_monitor_manager_get_primary_index (MetaMonitorManager *manager)
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_invalidate (MetaMonitorManager *manager)
|
||||
meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
*width = manager->screen_width;
|
||||
*height = manager->screen_height;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_handle_xevent (MetaMonitorManager *manager,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
@ -1165,6 +1207,15 @@ meta_monitor_manager_invalidate (MetaMonitorManager *manager)
|
||||
MetaMonitorMode *old_modes;
|
||||
int n_old_outputs;
|
||||
|
||||
if (manager->backend != META_BACKEND_XRANDR)
|
||||
return FALSE;
|
||||
|
||||
#ifdef HAVE_RANDR
|
||||
if ((event->type - manager->rr_event_base) != RRScreenChangeNotify)
|
||||
return FALSE;
|
||||
|
||||
XRRUpdateConfiguration (event);
|
||||
|
||||
/* Save the old structures, so they stay valid during the update */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
@ -1182,5 +1233,10 @@ meta_monitor_manager_invalidate (MetaMonitorManager *manager)
|
||||
free_output_array (old_outputs, n_old_outputs);
|
||||
g_free (old_modes);
|
||||
g_free (old_crtcs);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,10 +222,6 @@ void meta_screen_calc_workspace_layout (MetaScreen *screen,
|
||||
MetaWorkspaceLayout *layout);
|
||||
void meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout);
|
||||
|
||||
void meta_screen_resize (MetaScreen *screen,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_screen_minimize_all_on_active_workspace_except (MetaScreen *screen,
|
||||
MetaWindow *keep);
|
||||
|
||||
|
@ -510,6 +510,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
char buf[128];
|
||||
guint32 manager_timestamp;
|
||||
gulong current_workspace;
|
||||
MetaMonitorManager *manager;
|
||||
|
||||
replace_current_wm = meta_get_replace_current_wm ();
|
||||
|
||||
@ -668,8 +669,17 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->xscreen = ScreenOfDisplay (xdisplay, number);
|
||||
screen->xroot = xroot;
|
||||
screen->rect.x = screen->rect.y = 0;
|
||||
screen->rect.width = WidthOfScreen (screen->xscreen);
|
||||
screen->rect.height = HeightOfScreen (screen->xscreen);
|
||||
|
||||
meta_monitor_manager_initialize (screen->display->xdisplay);
|
||||
|
||||
manager = meta_monitor_manager_get ();
|
||||
g_signal_connect (manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), screen);
|
||||
|
||||
meta_monitor_manager_get_screen_size (manager,
|
||||
&screen->rect.width,
|
||||
&screen->rect.height);
|
||||
|
||||
screen->current_cursor = -1; /* invalid/unset */
|
||||
screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
|
||||
screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
|
||||
@ -694,17 +704,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
screen->compositor_data = NULL;
|
||||
screen->guard_window = None;
|
||||
|
||||
{
|
||||
MetaMonitorManager *manager;
|
||||
|
||||
meta_monitor_manager_initialize (screen->display->xdisplay);
|
||||
|
||||
reload_monitor_infos (screen);
|
||||
|
||||
manager = meta_monitor_manager_get ();
|
||||
g_signal_connect (manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), screen);
|
||||
}
|
||||
reload_monitor_infos (screen);
|
||||
|
||||
meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
|
||||
|
||||
@ -2845,23 +2845,16 @@ meta_screen_resize_func (MetaScreen *screen,
|
||||
meta_window_recalc_features (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_resize (MetaScreen *screen,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
screen->rect.width = width;
|
||||
screen->rect.height = height;
|
||||
|
||||
meta_monitor_manager_invalidate (meta_monitor_manager_get ());
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *manager,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
GSList *tmp, *windows;
|
||||
|
||||
meta_monitor_manager_get_screen_size (manager,
|
||||
&screen->rect.width,
|
||||
&screen->rect.height);
|
||||
|
||||
reload_monitor_infos (screen);
|
||||
set_desktop_geometry_hint (screen);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user