diff --git a/xfwm4-4.8.3/defaults/defaults b/xfwm4-4.8.3/defaults/defaults
index 1d7c97d..d21c4b3 100644
--- a/xfwm4-4.8.3/defaults/defaults
+++ b/xfwm4-4.8.3/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
title_alignment=center
title_font=Sans Bold 9
diff --git a/xfwm4-4.8.3/settings-dialogs/tweaks-settings.c b/xfwm4-4.8.3/settings-dialogs/tweaks-settings.c
index 4442ba2..722de23 100644
--- a/xfwm4-4.8.3/settings-dialogs/tweaks-settings.c
+++ b/xfwm4-4.8.3/settings-dialogs/tweaks-settings.c
@@ -197,6 +197,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"));
@@ -387,6 +388,10 @@ wm_tweaks_dialog_configure_widgets (GtkBuilder *builder)
"/general/show_dock_shadow",
G_TYPE_BOOLEAN,
(GObject *)show_dock_shadow_check, "active");
+ xfconf_g_property_bind (xfwm4_channel,
+ "/general/sync_to_vblank",
+ G_TYPE_BOOLEAN,
+ (GObject *)sync_to_vblank_check, "active");
xfconf_g_property_bind (xfwm4_channel,
"/general/frame_opacity",
diff --git a/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog.glade b/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog.glade
index a9e91ee..9a6e238 100644
--- a/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog.glade
+++ b/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog.glade
@@ -757,6 +757,20 @@ when switching via keyboard shortcuts
+
+
+ False
+ 4
+
+
+
False
- 4
+ 5
@@ -820,7 +834,7 @@ when switching via keyboard shortcuts
False
False
- 5
+ 6
@@ -834,7 +848,7 @@ when switching via keyboard shortcuts
False
False
- 6
+ 7
@@ -888,7 +902,7 @@ when switching via keyboard shortcuts
False
False
- 7
+ 8
@@ -902,7 +916,7 @@ when switching via keyboard shortcuts
False
False
- 8
+ 9
@@ -956,7 +970,7 @@ when switching via keyboard shortcuts
False
False
- 9
+ 10
@@ -970,7 +984,7 @@ when switching via keyboard shortcuts
False
False
- 10
+ 11
@@ -1024,7 +1038,7 @@ when switching via keyboard shortcuts
False
False
- 11
+ 12
@@ -1038,7 +1052,7 @@ when switching via keyboard shortcuts
False
False
- 12
+ 13
@@ -1092,7 +1106,7 @@ when switching via keyboard shortcuts
False
False
- 13
+ 14
diff --git a/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog_ui.h b/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog_ui.h
index 17fbdea..1339984 100644
--- a/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog_ui.h
+++ b/xfwm4-4.8.3/settings-dialogs/xfwm4-tweaks-dialog_ui.h
@@ -378,186 +378,194 @@ static const char tweaks_dialog_ui[] =
"se_underline\">TrueTrue
False3False4"
- "child>TrueTruediscontinuo"
- "usadjustment2FalseFalse1True<i>Opaque</i>TrueFalseFalse2"
- "object>FalseFalse5True0Opacity of _inactive win"
- "dows:Trueinactive_opacity_scale<"
- "packing>FalseFalse6"
- "child>True212TrueTrue<i>"
- "Transparent</i>TrueFalseFalse0TrueTruediscont"
- "inuousadjustment3FalseFalse
1True<i>Opaque</i>TrueFalseFalse<"
- "property name=\"position\">2FalseFalse7True0Opacity of windows "
- "during _move:Truemove_opacity_scaleFalseFalse8True2"
- "property>12True"
- "True<i"
- ">Transparent</i>True<"
- "/property>False<"
- "property name=\"fill\">False0TrueTruediscont"
- "inuousadjustment4FalseFalse
1True<i>Opaque</i>TrueFalseFalse<"
- "property name=\"position\">2FalseFalse9True0Opacity of windows "
- "during resi_ze:Trueresize_opacity_scale"
- "object>FalseFalse10"
- "True212TrueTrue&"
- "lt;i>Transparent</i>T"
- "rueFalseFalse"
- "0TrueTrued"
- "iscontinuousadjustment5FalseFalse1True<i>Opaque</i>TrueFalseFalse2"
- "FalseFalse11True"
- "0Opacity of po"
- "pup window_s:Truepopup_opacity_scaleFalseFalse12True2<"
- "/property>12TrueTrue<"
- "i>Transparent</i>True"
- "False"
- "False0"
- "property>TrueTruedisco"
- "ntinuousadjustment6"
- "FalseFalse1True<i>Opaque</i>True
FalseFalse2FalseFalse131<"
- "/child>5TrueC_ompositorTrue5False1<"
- "child internal-child=\"action_area\">Trueendgtk-helpTrueFalse<"
- "/property>TrueTrueTrueSynchronize drawing to the vertical blankTrueTrueFalseTrueTrueFals"
+ "e4<"
+ "child>True0Opaci_ty of window decorations:Trueframe_opacity_scaleFalse5True212True"
+ "True<i>Transparent</i>TrueFalse<"
+ "/property>False0True<"
+ "property name=\"can_focus\">Truediscontinuousadjustment2<"
+ "/property>FalseFalse1True<i>Opaque</i>True"
+ "FalseFalse"
+ "2"
+ "object>FalseFalse6True0Opacity"
+ " of _inactive windows:True<"
+ "/property>inactive_opacity_scaleFalseFalse0True"
- "gtk-closeTrueTrue"
- "TrueTrueFalseFalse1Falseend0button2but"
- "ton1"
+ "perty name=\"fill\">False7True212Tr"
+ "ueTrue<i>Transparent</i>TrueFals"
+ "eFalse0TrueTruediscontinuousadjustm"
+ "ent3FalseFalse1True<i>Opaque</i&g"
+ "t;TrueFalse"
+ "False2False"
+ "property>False8True0Op"
+ "acity of windows during _move:Truemove_opacity_scale"
+ "False"
+ "False9"
+ "property>True212"
+ "TrueTrue<i>Transparent</i>TrueF"
+ "alseFalse0TrueTruediscontinuousadjustmen"
+ "t4False"
+ "False1True"
+ "<i>Opaque</i>"
+ "TrueFalseFa"
+ "lse2FalseFalse10True0Opac"
+ "ity of windows during resi_ze:Trueresize_opacity_sca"
+ "leFalseFalse1"
+ "1True212TrueTrue
<i>Transparent</i>TrueFalseFalse0True"
+ "property>Truediscontinuousad"
+ "justment5FalseFalse"
+ "1True<i>Opaque<"
+ ";/i>TrueFalseFalse2"
+ "Fa"
+ "lseFalse12True0Opacity of popup window_s:Truepopup_opacity_scal"
+ "eFalseFalse13"
+ "True212"
+ "TrueTrue<i>Transparent</i>TrueF"
+ "alseFalse01True<i>Opaque</i>"
+ ";TrueFalseF"
+ "alse2FalseFalse14<"
+ "/object>15TrueC_ompositorTrue5False1True"
+ "endgtk-help"
+ "property>TrueFalseTrueTrue
TrueFalse"
+ "False0Truegtk-closeTrueTrueTrueTrueFalseFalse1Falseend0"
+ "button2button1"
};
-static const unsigned tweaks_dialog_ui_length = 37210u;
+static const unsigned tweaks_dialog_ui_length = 37702u;
diff --git a/xfwm4-4.8.3/src/compositor.c b/xfwm4-4.8.3/src/compositor.c
index c0ce4ea..221803b 100644
--- a/xfwm4-4.8.3/src/compositor.c
+++ b/xfwm4-4.8.3/src/compositor.c
@@ -36,6 +36,11 @@
#include
#include
+#include
+#include
+#include
+#include
+
#include "display.h"
#include "screen.h"
#include "client.h"
@@ -87,6 +92,7 @@
/* Set TIMEOUT_REPAINT to 0 to disable timeout repaint */
#define TIMEOUT_REPAINT 10 /* msec.) */
+#define TIMEOUT_DRI 10 /* seconds */
typedef struct _CWindow CWindow;
struct _CWindow
@@ -1243,6 +1249,66 @@ paint_win (CWindow *cw, XserverRegion region, gboolean solid_part)
}
}
+#if TIMEOUT_REPAINT
+
+static void
+open_dri(DisplayInfo *display_info)
+{
+ const char* dev = "/dev/dri/card0";
+ display_info->dri_fd = open(dev, O_RDWR);
+ if (display_info->dri_fd == -1)
+ g_warning ("Error opening %s: %s", dev, strerror(errno));
+}
+
+static void
+close_dri(DisplayInfo *display_info)
+{
+ close(display_info->dri_fd);
+ display_info->dri_fd = -1;
+}
+
+static void
+wait_vblank(DisplayInfo *display_info)
+{
+ int retval;
+ drm_wait_vblank_t vblank;
+ gint64 now;
+
+ now = g_get_monotonic_time();
+ if (display_info->dri_time > now)
+ return;
+
+ vblank.request.sequence = 1;
+ vblank.request.type = _DRM_VBLANK_RELATIVE;
+ if (display_info->dri_secondary)
+ vblank.request.type |= _DRM_VBLANK_SECONDARY;
+
+ do
+ {
+ retval = ioctl(display_info->dri_fd, DRM_IOCTL_WAIT_VBLANK, &vblank);
+ vblank.request.type &= ~_DRM_VBLANK_RELATIVE;
+ }
+ while (retval == -1 && errno == EINTR);
+
+ if (retval == -1)
+ {
+ /* if getting the vblank fails, try to get it from the other output */
+ display_info->dri_secondary = !display_info->dri_secondary;
+ g_warning ("Error waiting on vblank with DRI:%s, trying %s output",
+ strerror(errno), display_info->dri_secondary ? "secondary" : "primary");
+
+ /* 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(display_info);
+ open_dri(display_info);
+
+ //retry again in 10 seconds
+ display_info->dri_time = now + TIMEOUT_DRI * 1000000;
+ }
+}
+
+#endif
+
static void
paint_all (ScreenInfo *screen_info, XserverRegion region)
{
@@ -1254,6 +1320,10 @@ paint_all (ScreenInfo *screen_info, XserverRegion region)
gint screen_height;
CWindow *cw;
+#if TIMEOUT_REPAINT
+ gboolean use_dri;
+#endif
+
TRACE ("entering paint_all");
g_return_if_fail (screen_info);
@@ -1402,8 +1472,24 @@ 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);
+
+#if TIMEOUT_REPAINT
+ use_dri = screen_info->params->sync_to_vblank && screen_info->display_info->dri_fd != -1;
+ /*sync all previous rendering commands, tell xlib to render the pixmap onto the root window,
+ wait for the vblank, then flush, this minimizes tearing*/
+ if (use_dri)
+ XSync(dpy, False);
+#endif
XRenderComposite (dpy, PictOpSrc, screen_info->rootBuffer, None, screen_info->rootPicture,
0, 0, 0, 0, 0, 0, screen_width, screen_height);
+#if TIMEOUT_REPAINT
+ if (use_dri)
+ {
+ wait_vblank(screen_info->display_info);
+ XFlush(dpy);
+ }
+#endif
+
XFixesDestroyRegion (dpy, paint_region);
}
@@ -2841,6 +2927,10 @@ compositorInitDisplay (DisplayInfo *display_info)
display_info->have_overlays = ((composite_major > 0) || (composite_minor >= 3));
#endif /* HAVE_OVERLAYS */
+ display_info->dri_fd = -1;
+ display_info->dri_secondary = FALSE;
+ display_info->dri_time = 0;
+
#else /* HAVE_COMPOSITOR */
display_info->enable_compositor = FALSE;
#endif /* HAVE_COMPOSITOR */
@@ -2967,6 +3057,8 @@ compositorManageScreen (ScreenInfo *screen_info)
compositorSetCMSelection (screen_info, screen_info->xfwm4_win);
TRACE ("Manual compositing enabled");
+ open_dri(display_info);
+
return TRUE;
#else
return FALSE;
@@ -3059,6 +3151,8 @@ compositorUnmanageScreen (ScreenInfo *screen_info)
display_info->composite_mode);
compositorSetCMSelection (screen_info, None);
+
+ close_dri(display_info);
#endif /* HAVE_COMPOSITOR */
}
diff --git a/xfwm4-4.8.3/src/display.h b/xfwm4-4.8.3/src/display.h
index 6bf7094..21944f6 100644
--- a/xfwm4-4.8.3/src/display.h
+++ b/xfwm4-4.8.3/src/display.h
@@ -355,6 +355,10 @@ struct _DisplayInfo
gboolean have_overlays;
#endif /* HAVE_OVERLAYS */
+ gint dri_fd;
+ gboolean dri_secondary;
+ gint64 dri_time;
+
#endif /* HAVE_COMPOSITOR */
};
diff --git a/xfwm4-4.8.3/src/settings.c b/xfwm4-4.8.3/src/settings.c
index 0a9581e..901c379 100644
--- a/xfwm4-4.8.3/src/settings.c
+++ b/xfwm4-4.8.3/src/settings.c
@@ -714,6 +714,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},
{"title_alignment", NULL, G_TYPE_STRING, TRUE},
{"title_font", NULL, G_TYPE_STRING, FALSE},
@@ -816,6 +817,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->toggle_workspaces =
getBoolValue ("toggle_workspaces", rc);
screen_info->params->unredirect_overlays =
@@ -1320,6 +1323,10 @@ cb_xfwm4_channel_property_changed(XfconfChannel *channel, const gchar *property_
{
screen_info->params->snap_resist = 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/xfwm4-4.8.3/src/settings.h b/xfwm4-4.8.3/src/settings.h
index 76ffa62..7042741 100644
--- a/xfwm4-4.8.3/src/settings.h
+++ b/xfwm4-4.8.3/src/settings.h
@@ -218,6 +218,7 @@ struct _XfwmParams
gboolean snap_resist;
gboolean snap_to_border;
gboolean snap_to_windows;
+ gboolean sync_to_vblank;
gboolean title_vertical_offset_active;
gboolean title_vertical_offset_inactive;
gboolean toggle_workspaces;