summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/display.c33
-rw-r--r--src/core/monitor-private.h7
-rw-r--r--src/core/monitor.c122
-rw-r--r--src/core/screen-private.h4
-rw-r--r--src/core/screen.c41
5 files changed, 122 insertions, 85 deletions
diff --git a/src/core/display.c b/src/core/display.c
index e39361e83..64f5511c1 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -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 */
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index 93f5ebca5..c159d2b21 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -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
diff --git a/src/core/monitor.c b/src/core/monitor.c
index e109bfc36..0a3aba145 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -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
}
diff --git a/src/core/screen-private.h b/src/core/screen-private.h
index 894eda5e4..9e0da8d7a 100644
--- a/src/core/screen-private.h
+++ b/src/core/screen-private.h
@@ -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);
diff --git a/src/core/screen.c b/src/core/screen.c
index cb02f201b..86f462d2f 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -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);