Another attempt at getting Xrandr screen size changes right. Actually

* gdk/x11/gdkevents-x11.c:
        * gdk/x11/gdkscreen-x11.[hc]: Another attempt at getting Xrandr
        screen size changes right. Actually handle XRRScreenChangeNotify
        events, and ignore root ConfigureNotify events if we are using
        Xrandr. Only emit size-changed signals if the screen size changed,
        and only emit monitor-changed signals if the monitors changed.


svn path=/trunk/; revision=22398
This commit is contained in:
Matthias Clasen 2009-02-24 05:09:13 +00:00
parent 7d8930fdcc
commit fcdd092ae6
4 changed files with 109 additions and 34 deletions

View File

@ -1,3 +1,12 @@
2009-02-24 Matthias Clasen <mclasen@redhat.com>
* gdk/x11/gdkevents-x11.c:
* gdk/x11/gdkscreen-x11.[hc]: Another attempt at getting Xrandr
screen size changes right. Actually handle XRRScreenChangeNotify
events, and ignore root ConfigureNotify events if we are using
Xrandr. Only emit size-changed signals if the screen size changed,
and only emit monitor-changed signals if the monitors changed.
2009-02-23 Matthias Clasen <mclasen@redhat.com>
Bug 565199 Ellipsize text in Places list

View File

@ -2107,10 +2107,11 @@ gdk_event_translate (GdkDisplay *display,
else
#endif
#ifdef HAVE_RANDR
if (xevent->type - display_x11->xrandr_event_base == RRNotify)
if (xevent->type - display_x11->xrandr_event_base == RRScreenChangeNotify ||
xevent->type - display_x11->xrandr_event_base == RRNotify)
{
if (screen)
_gdk_x11_screen_process_monitors_change (screen);
_gdk_x11_screen_size_changed (screen, xevent);
}
else
#endif

View File

@ -1,4 +1,4 @@
/*
/*
* gdkscreen-x11.c
*
* Copyright 2001 Sun Microsystems Inc.
@ -856,34 +856,79 @@ init_xfree_xinerama (GdkScreen *screen)
return FALSE;
}
static void
free_monitors (GdkX11Monitor *monitors,
gint n_monitors)
{
int i;
for (i = 0; i < n_monitors; ++i)
{
g_free (monitors[i].output_name);
g_free (monitors[i].manufacturer);
}
g_free (monitors);
}
static void
deinit_multihead (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
int i;
for (i = 0; i < screen_x11->n_monitors; ++i)
{
GdkX11Monitor *monitor = get_monitor (screen, i);
g_free (monitor->output_name);
g_free (monitor->manufacturer);
}
g_free (screen_x11->monitors);
free_monitors (screen_x11->monitors, screen_x11->n_monitors);
screen_x11->n_monitors = 0;
screen_x11->monitors = NULL;
}
static gboolean
compare_monitor (GdkX11Monitor *m1,
GdkX11Monitor *m2)
{
if (m1->geometry.x != m2->geometry.x ||
m1->geometry.y != m2->geometry.y ||
m1->geometry.width != m2->geometry.width ||
m1->geometry.height != m2->geometry.height)
return FALSE;
if (m1->width_mm != m2->width_mm ||
m1->height_mm != m2->height_mm)
return FALSE;
if (g_strcmp0 (m1->output_name, m2->output_name) != 0)
return FALSE;
if (g_strcmp0 (m1->manufacturer, m2->manufacturer) != 0)
return FALSE;
return TRUE;
}
static gboolean
compare_monitors (GdkX11Monitor *monitors1, gint n_monitors1,
GdkX11Monitor *monitors2, gint n_monitors2)
{
gint i;
if (n_monitors1 != n_monitors2)
return FALSE;
for (i = 0; i < n_monitors1; i++)
{
if (!compare_monitor (monitors1 + i, monitors2 + i))
return FALSE;
}
return TRUE;
}
static void
init_multihead (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
int opcode, firstevent, firsterror;
deinit_multihead (screen);
/* There are four different implementations of multihead support:
*
* 1. Fake Xinerama for debugging purposes
@ -995,18 +1040,49 @@ init_randr_support (GdkScreen * screen)
#endif
}
static void
process_monitors_change (GdkScreen *screen)
{
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
gint n_monitors;
GdkX11Monitor *monitors;
gboolean changed;
n_monitors = screen_x11->n_monitors;
monitors = screen_x11->monitors;
screen_x11->n_monitors = 0;
screen_x11->monitors = NULL;
init_multihead (screen);
changed = !compare_monitors (monitors, n_monitors,
screen_x11->monitors, screen_x11->n_monitors);
free_monitors (monitors, n_monitors);
if (changed)
g_signal_emit_by_name (screen, "monitors-changed");
}
void
_gdk_x11_screen_size_changed (GdkScreen *screen,
XEvent *event)
{
gint width, height;
GdkDisplayX11 *display_x11;
gboolean monitors_changed;
width = gdk_screen_get_width (screen);
height = gdk_screen_get_height (screen);
#ifdef HAVE_RANDR
if (!XRRUpdateConfiguration (event))
display_x11 = GDK_DISPLAY_X11 (gdk_screen_get_display (screen));
if (display_x11->have_randr13 && event->type == ConfigureNotify)
return;
XRRUpdateConfiguration (event);
#else
if (event->type == ConfigureNotify)
{
@ -1020,21 +1096,11 @@ _gdk_x11_screen_size_changed (GdkScreen *screen,
return;
#endif
if (width == gdk_screen_get_width (screen) &&
height == gdk_screen_get_height (screen))
return;
process_monitors_change (screen);
_gdk_x11_screen_process_monitors_change (screen);
g_signal_emit_by_name (screen, "size-changed");
}
void
_gdk_x11_screen_process_monitors_change (GdkScreen *screen)
{
init_multihead (screen);
g_signal_emit_by_name (screen, "monitors-changed");
if (width != gdk_screen_get_width (screen) ||
height != gdk_screen_get_height (screen))
g_signal_emit_by_name (screen, "size-changed");
}
void
@ -1061,7 +1127,7 @@ _gdk_x11_screen_process_owner_change (GdkScreen *screen,
{
screen_x11->is_composited = composited;
g_signal_emit_by_name (screen, "composited_changed");
g_signal_emit_by_name (screen, "composited-changed");
}
}
#endif

View File

@ -125,9 +125,8 @@ GdkScreen * _gdk_x11_screen_new (GdkDisplay *display,
void _gdk_x11_screen_window_manager_changed (GdkScreen *screen);
void _gdk_x11_screen_size_changed (GdkScreen *screen,
XEvent *event);
void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
XEvent *event);
void _gdk_x11_screen_process_monitors_change (GdkScreen *screen);
void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
XEvent *event);
G_END_DECLS