[Xfce4-commits] <xfwm4:master> Add Vsync support for the compositor (bug #8898).

Nick Schermer noreply at xfce.org
Wed May 8 21:18:02 CEST 2013


Updating branch refs/heads/master
         to 22d6df280117fba8eb7584bca631d73a7ba359e2 (commit)
       from 703bd36d23974c195ff0877c13b5bcfc2d56623c (commit)

commit 22d6df280117fba8eb7584bca631d73a7ba359e2
Author: Bob Loosen <bob.loosen at gmail.com>
Date:   Wed May 8 21:08:46 2013 +0200

    Add Vsync support for the compositor (bug #8898).

 configure.ac.in                            |    9 +
 defaults/defaults                          |    1 +
 settings-dialogs/tweaks-settings.c         |    9 +
 settings-dialogs/xfwm4-tweaks-dialog.glade |   40 +++--
 src/Makefile.am                            |    3 +-
 src/compositor.c                           |  255 +++++++++++++++++++++++++++-
 src/screen.h                               |   13 ++
 src/settings.c                             |    7 +
 src/settings.h                             |    1 +
 9 files changed, 324 insertions(+), 14 deletions(-)

diff --git a/configure.ac.in b/configure.ac.in
index 9aa2617..9d90dac 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -19,6 +19,7 @@ m4_define([xcomposite_minimum_version], [0.2])
 m4_define([wnck_minimum_version], [2.22])
 m4_define([startup_notification_minimum_version], [0.5])
 m4_define([intltool_minimum_version], [0.31])
+m4_define([libdrm_minimum_version], [2.4])
 
 dnl init autoconf
 AC_COPYRIGHT([Copyright (c) 2002-2011
@@ -90,6 +91,14 @@ XDT_CHECK_PACKAGE([DBUS], [dbus-1], [1.0.0])
 XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.72])
 
 dnl
+dnl Sync to vblank support
+dnl
+XDT_CHECK_OPTIONAL_PACKAGE([LIBDRM],
+                       [libdrm], [libdrm_minimum_version],
+                       [libdrm],
+                       [userspace interface to the kernel DRM services], [yes])
+
+dnl
 dnl Startup notification support
 dnl
 LIBSTARTUP_NOTIFICATION_FOUND="no"
diff --git a/defaults/defaults b/defaults/defaults
index 6db210a..17dc3d7 100644
--- a/defaults/defaults
+++ b/defaults/defaults
@@ -49,6 +49,7 @@ snap_resist=false
 snap_to_border=true
 snap_to_windows=false
 snap_width=10
+sync_to_vblank=false
 theme=Default
 tile_on_move=true
 title_alignment=center
diff --git a/settings-dialogs/tweaks-settings.c b/settings-dialogs/tweaks-settings.c
index f60b606..0b6a7eb 100644
--- a/settings-dialogs/tweaks-settings.c
+++ b/settings-dialogs/tweaks-settings.c
@@ -205,6 +205,7 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
     GtkWidget *show_frame_shadow_check = GTK_WIDGET (gtk_builder_get_object (builder, "show_frame_shadow_check"));
     GtkWidget *show_popup_shadow_check = GTK_WIDGET (gtk_builder_get_object (builder, "show_popup_shadow_check"));
     GtkWidget *show_dock_shadow_check = GTK_WIDGET (gtk_builder_get_object (builder, "show_dock_shadow_check"));
+    GtkWidget *sync_to_vblank_check = GTK_WIDGET (gtk_builder_get_object (builder, "sync_to_vblank_check"));
 
     GtkWidget *frame_opacity_scale = GTK_WIDGET (gtk_builder_get_object (builder, "frame_opacity_scale"));
     GtkWidget *inactive_opacity_scale = GTK_WIDGET (gtk_builder_get_object (builder, "inactive_opacity_scale"));
@@ -405,6 +406,14 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
                             "/general/show_dock_shadow",
                             G_TYPE_BOOLEAN,
                             (GObject *)show_dock_shadow_check, "active");
+#ifdef HAVE_LIBDRM
+    xfconf_g_property_bind (xfwm4_channel,
+                            "/general/sync_to_vblank",
+                            G_TYPE_BOOLEAN,
+                            (GObject *)sync_to_vblank_check, "active");
+#else
+    gtk_widget_hide (sync_to_vblank_check);
+#endif
 
     xfconf_g_property_bind (xfwm4_channel,
                             "/general/frame_opacity",
diff --git a/settings-dialogs/xfwm4-tweaks-dialog.glade b/settings-dialogs/xfwm4-tweaks-dialog.glade
index e9996af..d026dfd 100644
--- a/settings-dialogs/xfwm4-tweaks-dialog.glade
+++ b/settings-dialogs/xfwm4-tweaks-dialog.glade
@@ -840,8 +840,8 @@ when switching via keyboard shortcuts</property>
                                   </packing>
                                 </child>
                                 <child>
-                                  <object class="GtkCheckButton" id="show_frame_shadow_check">
-                                    <property name="label" translatable="yes">Show shadows under _regular windows</property>
+                                  <object class="GtkCheckButton" id="sync_to_vblank_check">
+                                    <property name="label" translatable="yes">Synchronize drawing to the _vertical blank</property>
                                     <property name="use_action_appearance">False</property>
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
@@ -888,6 +888,22 @@ when switching via keyboard shortcuts</property>
                                   </packing>
                                 </child>
                                 <child>
+                                  <object class="GtkCheckButton" id="show_frame_shadow_check">
+                                    <property name="label" translatable="yes">Show shadows under _regular windows</property>
+                                    <property name="use_action_appearance">False</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="use_underline">True</property>
+                                    <property name="draw_indicator">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">4</property>
+                                  </packing>
+                                </child>
+                                <child>
                                   <object class="GtkLabel" id="label12">
                                     <property name="visible">True</property>
                                     <property name="can_focus">False</property>
@@ -899,7 +915,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">True</property>
-                                    <property name="position">4</property>
+                                    <property name="position">5</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -959,7 +975,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">5</property>
+                                    <property name="position">6</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -974,7 +990,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">6</property>
+                                    <property name="position">7</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1034,7 +1050,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">7</property>
+                                    <property name="position">8</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1049,7 +1065,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">8</property>
+                                    <property name="position">9</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1109,7 +1125,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">9</property>
+                                    <property name="position">10</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1124,7 +1140,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">10</property>
+                                    <property name="position">11</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1184,7 +1200,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">11</property>
+                                    <property name="position">12</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1199,7 +1215,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">12</property>
+                                    <property name="position">13</property>
                                   </packing>
                                 </child>
                                 <child>
@@ -1259,7 +1275,7 @@ when switching via keyboard shortcuts</property>
                                   <packing>
                                     <property name="expand">False</property>
                                     <property name="fill">False</property>
-                                    <property name="position">13</property>
+                                    <property name="position">14</property>
                                   </packing>
                                 </child>
                               </object>
diff --git a/src/Makefile.am b/src/Makefile.am
index f92e3f9..ee2fff6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,6 +80,7 @@ xfwm4_CFLAGS =								\
 	$(LIBXFCE4UI_CFLAGS)						\
 	$(LIBXFCE4KBD_PRIVATE_CFLAGS)					\
 	$(RENDER_CFLAGS)						\
+	$(LIBDRM_CFLAGS)						\
 	$(LIBSTARTUP_NOTIFICATION_CFLAGS)				\
 	$(COMPOSITOR_CFLAGS)						\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
@@ -101,7 +102,7 @@ xfwm4_LDADD =								\
 	$(RENDER_LIBS)							\
 	$(COMPOSITOR_LIBS)						\
 	$(RANDR_LIBS) 							\
-	$(MATH_LIBS)	
+	$(MATH_LIBS)
 
 EXTRA_DIST = 								\
 	default_icon.png						\
diff --git a/src/compositor.c b/src/compositor.c
index 428989c..03607d0 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -36,6 +36,14 @@
 #include <string.h>
 #include <libxfce4util/libxfce4util.h>
 
+#ifdef HAVE_LIBDRM
+#include <stdint.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <drm.h>
+#include <stropts.h>
+#endif /* HAVE_LIBDRM */
+
 #include "display.h"
 #include "screen.h"
 #include "client.h"
@@ -86,7 +94,12 @@
 #define WIN_IS_REDIRECTED(cw)           (cw->redirected)
 
 /* Set TIMEOUT_REPAINT to 0 to disable timeout repaint */
-#define TIMEOUT_REPAINT       10 /* msec.) */
+#define TIMEOUT_REPAINT       10 /* msec */
+#define TIMEOUT_REPAINT_MIN    1
+#define TIMEOUT_REPAINT_MAX   20
+#define TIMEOUT_DRI           10 /* seconds */
+
+#define DRM_CARD0             "/dev/dri/card0"
 
 typedef struct _CWindow CWindow;
 struct _CWindow
@@ -1247,6 +1260,113 @@ paint_win (CWindow *cw, XserverRegion region, gboolean solid_part)
     }
 }
 
+#if HAVE_LIBDRM
+#if TIMEOUT_REPAINT
+
+static void
+open_dri (ScreenInfo *screen_info)
+{
+    screen_info->dri_fd = open (DRM_CARD0, O_RDWR);
+    if (screen_info->dri_fd == -1)
+    {
+        g_warning ("Error opening %s: %s", DRM_CARD0, g_strerror (errno));
+    }
+}
+
+static void
+close_dri (ScreenInfo *screen_info)
+{
+    if (screen_info->dri_fd != -1)
+    {
+        close (screen_info->dri_fd);
+        screen_info->dri_fd = -1;
+    }
+}
+
+static gboolean
+dri_enabled (ScreenInfo *screen_info)
+{
+    return (screen_info->dri_fd != -1 && screen_info->params->sync_to_vblank);
+}
+
+static void
+wait_vblank (ScreenInfo *screen_info)
+{
+    int retval;
+    drm_wait_vblank_t vblank;
+
+    if (screen_info->dri_time > g_get_monotonic_time())
+    {
+        return;
+    }
+
+    vblank.request.sequence = 1;
+    vblank.request.type = _DRM_VBLANK_RELATIVE;
+    if (screen_info->dri_secondary)
+    {
+        vblank.request.type |= _DRM_VBLANK_SECONDARY;
+    }
+
+    do
+    {
+       retval = ioctl (screen_info->dri_fd, DRM_IOCTL_WAIT_VBLANK, &vblank);
+       vblank.request.type &= ~_DRM_VBLANK_RELATIVE;
+    }
+    while (retval == -1 && errno == EINTR);
+
+    screen_info->vblank_time = g_get_monotonic_time ();
+
+    if (retval == -1)
+    {
+        if (screen_info->dri_success)
+        {
+            screen_info->dri_success = FALSE;
+            g_warning ("Error waiting on vblank with DRI: %s", g_strerror (errno));
+        }
+
+        /* if getting the vblank fails, try to get it from the other output */
+        screen_info->dri_secondary = !screen_info->dri_secondary;
+
+        /* the output that we tried to get the vblank from might be disabled,
+           if that's the case, the device needs to be reopened, or it will continue to fail */
+        close_dri (screen_info);
+        open_dri (screen_info);
+
+        /* retry in 10 seconds */
+        screen_info->dri_time = g_get_monotonic_time() + TIMEOUT_DRI * 1000000;
+    }
+    else if (!screen_info->dri_success)
+    {
+        g_message ("Using vertical blank of %s DRI output",
+                   screen_info->dri_secondary ? "secondary" : "primary");
+
+        screen_info->dri_success = TRUE;
+    }
+}
+
+#ifdef HAVE_RANDR
+static void
+get_refresh_rate (ScreenInfo* screen_info)
+{
+    gint refresh_rate;
+    XRRScreenConfiguration* randr_info;
+
+    randr_info = XRRGetScreenInfo (screen_info->display_info->dpy, screen_info->xroot);
+    refresh_rate = XRRConfigCurrentRate (randr_info);
+    XRRFreeScreenConfigInfo (randr_info);
+
+    if (refresh_rate != screen_info->refresh_rate)
+    {
+        g_message ("Detected refreshrate:%i hertz", refresh_rate);
+        screen_info->refresh_rate = refresh_rate;
+    }
+}
+#endif /* HAVE_RANDR */
+
+#endif /* TIMEOUT_REPAINT */
+
+#endif /* HAVE_LIBDRM */
+
 static void
 paint_all (ScreenInfo *screen_info, XserverRegion region)
 {
@@ -1258,6 +1378,12 @@ paint_all (ScreenInfo *screen_info, XserverRegion region)
     gint screen_height;
     CWindow *cw;
 
+#ifdef HAVE_LIBDRM
+#if TIMEOUT_REPAINT
+    gboolean use_dri;
+#endif /* TIMEOUT_REPAINT */
+#endif /* HAVE_LIBDRM */
+
     TRACE ("entering paint_all");
     g_return_if_fail (screen_info);
 
@@ -1406,8 +1532,34 @@ paint_all (ScreenInfo *screen_info, XserverRegion region)
     TRACE ("Copying data back to screen");
     /* Set clipping back to the given region */
     XFixesSetPictureClipRegion (dpy, screen_info->rootBuffer, 0, 0, region);
+
+#ifdef HAVE_LIBDRM
+#if TIMEOUT_REPAINT
+    use_dri = dri_enabled (screen_info);
+    
+    if (use_dri)
+    {
+        /* sync all previous rendering commands, tell xlib to render the pixmap
+         * onto the root window, wait for the vblank, then flush, this minimizes
+         * tearing*/
+        XFlush (dpy);
+    }
+#endif /* TIMEOUT_REPAINT */
+#endif /* HAVE_LIBDRM */
+
     XRenderComposite (dpy, PictOpSrc, screen_info->rootBuffer, None, screen_info->rootPicture,
                       0, 0, 0, 0, 0, 0, screen_width, screen_height);
+
+#ifdef HAVE_LIBDRM
+#if TIMEOUT_REPAINT
+    if (use_dri)
+    {
+        wait_vblank (screen_info);
+        XFlush (dpy);
+    }
+#endif /* TIMEOUT_REPAINT */
+#endif /* HAVE_LIBDRM */
+
     XFixesDestroyRegion (dpy, paint_region);
 }
 
@@ -1467,13 +1619,57 @@ static void
 add_repair (ScreenInfo *screen_info)
 {
 #if TIMEOUT_REPAINT
+#ifdef HAVE_LIBDRM
+    gint64 interval;
+#endif /* HAVE_LIBDRM */
+
     if (screen_info->compositor_timeout_id != 0)
     {
         return;
     }
+
+#ifdef HAVE_LIBDRM
+    if (dri_enabled (screen_info))
+    {
+        /* schedule the next render to be half a refresh period after the last vertical blank,
+           but at least 1 ms in the future so that all queued events can be processed,
+           and to reduce latency if we didn't render for a while */
+#ifdef HAVE_RANDR
+        if (screen_info->refresh_rate > 0)
+        {
+            interval = (screen_info->vblank_time + 500000 / screen_info->refresh_rate -
+                        g_get_monotonic_time ()) / 1000;
+        }
+        else
+#endif /* HAVE_RANDR */
+        {
+            interval = TIMEOUT_REPAINT - ((g_get_monotonic_time () - screen_info->vblank_time) / 1000);
+        }
+
+        if (interval > TIMEOUT_REPAINT_MAX)
+        {
+            interval = TIMEOUT_REPAINT_MAX;
+        }
+        else if (interval < TIMEOUT_REPAINT_MIN)
+        {
+            interval = TIMEOUT_REPAINT_MIN;
+        }
+    }
+    else
+    {
+        interval = TIMEOUT_REPAINT;
+    }
+#endif /* HAVE_LIBDRM */
+
     screen_info->compositor_timeout_id =
+#ifdef HAVE_LIBDRM
+        g_timeout_add (interval,
+                       compositor_timeout_cb, screen_info);
+#else
         g_timeout_add (TIMEOUT_REPAINT,
                        compositor_timeout_cb, screen_info);
+#endif /*HAVE_LIBDRM */
+
 #endif /* TIMEOUT_REPAINT */
 }
 
@@ -2543,6 +2739,26 @@ compositorHandleShapeNotify (DisplayInfo *display_info, XShapeEvent *ev)
     }
 }
 
+#ifdef HAVE_LIBDRM
+#ifdef HAVE_RANDR
+static void
+compositorHandleRandrNotify (DisplayInfo *display_info, XRRScreenChangeNotifyEvent *ev)
+{
+    ScreenInfo *screen_info;
+
+    g_return_if_fail (display_info != NULL);
+    g_return_if_fail (ev != NULL);
+    TRACE ("entering compositorHandleRandrNotify for 0x%lx", ev->window);
+
+    screen_info = myDisplayGetScreenFromRoot (display_info, ev->window);
+    if (screen_info)
+        get_refresh_rate (screen_info);
+
+    XRRUpdateConfiguration ((XEvent *) ev);
+}
+#endif /* HAVE_RANDR */
+#endif /* HAVE_LIBDRM */
+
 static void
 compositorSetCMSelection (ScreenInfo *screen_info, Window w)
 {
@@ -2753,6 +2969,15 @@ compositorHandleEvent (DisplayInfo *display_info, XEvent *ev)
     {
         compositorHandleShapeNotify (display_info, (XShapeEvent *) ev);
     }
+#ifdef HAVE_LIBDRM
+#ifdef HAVE_RANDR
+    else if (ev->type == (display_info->xrandr_event_base + RRScreenChangeNotify))
+    {
+        compositorHandleRandrNotify (display_info, (XRRScreenChangeNotifyEvent *) ev);
+    }
+#endif /* HAVE_RANDR */
+#endif /* HAVE_LIBDRM */
+
 #if TIMEOUT_REPAINT == 0
     repair_display (display_info);
 #endif /* TIMEOUT_REPAINT */
@@ -2971,6 +3196,22 @@ compositorManageScreen (ScreenInfo *screen_info)
     compositorSetCMSelection (screen_info, screen_info->xfwm4_win);
     TRACE ("Manual compositing enabled");
 
+#ifdef HAVE_LIBDRM
+    open_dri (screen_info);
+    screen_info->dri_success = TRUE;
+    screen_info->dri_secondary = FALSE;
+    screen_info->dri_time = 0;
+    screen_info->vblank_time = 0;
+
+#ifdef HAVE_RANDR
+    if (display_info->have_xrandr)
+    {
+        get_refresh_rate(screen_info);
+        XRRSelectInput(display_info->dpy, screen_info->xroot, RRScreenChangeNotifyMask);
+    }
+#endif /* HAVE_RANDR */
+#endif /* HAVE_LIBDRM */
+
     return TRUE;
 #else
     return FALSE;
@@ -3063,6 +3304,18 @@ compositorUnmanageScreen (ScreenInfo *screen_info)
                                     display_info->composite_mode);
 
     compositorSetCMSelection (screen_info, None);
+
+#ifdef HAVE_LIBDRM
+    close_dri (screen_info);
+
+#ifdef HAVE_RANDR
+    if (display_info->have_xrandr)
+    {
+        XRRSelectInput (display_info->dpy, screen_info->xroot, 0);
+    }
+#endif /* HAVE_RANDR */
+#endif /* HAVE_LIBDRM */
+
 #endif /* HAVE_COMPOSITOR */
 }
 
diff --git a/src/screen.h b/src/screen.h
index 88e4845..a2b25c0 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -181,6 +181,19 @@ struct _ScreenInfo
     gboolean damages_pending;
 
     guint compositor_timeout_id;
+
+#ifdef HAVE_LIBDRM
+    gint dri_fd;
+    gboolean dri_secondary;
+    gboolean dri_success;
+    gint64 dri_time;
+    gint64 vblank_time;
+
+#ifdef HAVE_RANDR
+    gint refresh_rate;
+#endif /* HAVE_RANDR */
+#endif /* HAVE_LIBDRM */
+
 #endif /* HAVE_COMPOSITOR */
 };
 
diff --git a/src/settings.c b/src/settings.c
index 607bb7b..a8a9e06 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -720,6 +720,7 @@ loadSettings (ScreenInfo *screen_info)
         {"snap_to_border", NULL, G_TYPE_BOOLEAN, TRUE},
         {"snap_to_windows", NULL, G_TYPE_BOOLEAN, TRUE},
         {"snap_width", NULL, G_TYPE_INT, TRUE},
+        {"sync_to_vblank", NULL, G_TYPE_BOOLEAN, TRUE},
         {"theme", NULL, G_TYPE_STRING, TRUE},
         {"tile_on_move", NULL, G_TYPE_BOOLEAN, TRUE},
         {"title_alignment", NULL, G_TYPE_STRING, TRUE},
@@ -823,6 +824,8 @@ loadSettings (ScreenInfo *screen_info)
         getBoolValue ("snap_resist", rc);
     screen_info->params->snap_width =
         getIntValue ("snap_width", rc);
+    screen_info->params->sync_to_vblank =
+        getBoolValue ("sync_to_vblank", rc);
     screen_info->params->tile_on_move =
         getBoolValue ("tile_on_move", rc);
     screen_info->params->toggle_workspaces =
@@ -1329,6 +1332,10 @@ cb_xfwm4_channel_property_changed(XfconfChannel *channel, const gchar *property_
                 {
                     screen_info->params->tile_on_move = g_value_get_boolean (value);
                 }
+                else if (!strcmp (name, "sync_to_vblank"))
+                {
+                    screen_info->params->sync_to_vblank = g_value_get_boolean (value);
+                }
                 else if (!strcmp (name, "toggle_workspaces"))
                 {
                     screen_info->params->toggle_workspaces = g_value_get_boolean (value);
diff --git a/src/settings.h b/src/settings.h
index be01b6b..d595ddc 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -223,6 +223,7 @@ struct _XfwmParams
     gboolean snap_resist;
     gboolean snap_to_border;
     gboolean snap_to_windows;
+    gboolean sync_to_vblank;
     gboolean tile_on_move;
     gboolean title_vertical_offset_active;
     gboolean title_vertical_offset_inactive;


More information about the Xfce4-commits mailing list