Module: wine
Branch: master
Commit: 59c206f9dc25a9f9cfd772bf87288b7fb65f355f
URL: https://source.winehq.org/git/wine.git/?a=commit;h=59c206f9dc25a9f9cfd772bf…
Author: Zhiyi Zhang <zzhang(a)codeweavers.com>
Date: Tue Jun 30 17:56:53 2020 +0800
winex11.drv: Use _GTK_WORKAREAS to get work areas if it is available.
_NET_WORKAREA reports a single rectangle as intersected work areas of
all monitors. So work areas on non-primary monitors may be incorrect.
For example, a dock only shown on the primary monitor reduces the work
areas on non-primary monitors.
There were attempts to extend _NET_WORKAREA to support work areas of
multiple monitors but they were rejected as EWMH is no longer being
maintained and _GTK_WORKAREAS was introduced instead.
Fix Office 2010 missing title bar on non-primary monitors on GNOME.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/winex11.drv/display.c | 29 ++++++++++++++++++++++++++++-
dlls/winex11.drv/x11drv.h | 1 +
dlls/winex11.drv/x11drv_main.c | 1 +
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 3952098ad4..27876e02df 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -263,10 +263,37 @@ RECT get_work_area(const RECT *monitor_rect)
{
Atom type;
int format;
- unsigned long count, remaining;
+ unsigned long count, remaining, i;
long *work_area;
RECT work_rect;
+ /* Try _GTK_WORKAREAS first as _NET_WORKAREA may be incorrect on multi-monitor systems */
+ if (!XGetWindowProperty(gdi_display, DefaultRootWindow(gdi_display),
+ x11drv_atom(_GTK_WORKAREAS_D0), 0, ~0, False, XA_CARDINAL, &type,
+ &format, &count, &remaining, (unsigned char **)&work_area))
+ {
+ if (type == XA_CARDINAL && format == 32 && count >= 4)
+ {
+ for (i = 0; i + 3 < count; i += 4)
+ {
+ work_rect.left = work_area[i * 4];
+ work_rect.top = work_area[i * 4 + 1];
+ work_rect.right = work_rect.left + work_area[i * 4 + 2];
+ work_rect.bottom = work_rect.top + work_area[i * 4 + 3];
+
+ if (IntersectRect(&work_rect, &work_rect, monitor_rect))
+ {
+ TRACE("work_rect:%s.\n", wine_dbgstr_rect(&work_rect));
+ XFree(work_area);
+ return work_rect;
+ }
+ }
+ }
+ XFree(work_area);
+ }
+
+ WARN("_GTK_WORKAREAS is not supported, fallback to _NET_WORKAREA. "
+ "Work areas may be incorrect on multi-monitor systems.\n");
if (!XGetWindowProperty(gdi_display, DefaultRootWindow(gdi_display), x11drv_atom(_NET_WORKAREA),
0, ~0, False, XA_CARDINAL, &type, &format, &count, &remaining,
(unsigned char **)&work_area))
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 328b9561ae..9bbb48f1ee 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -464,6 +464,7 @@ enum x11drv_atoms
XATOM__NET_WM_WINDOW_TYPE_NORMAL,
XATOM__NET_WM_WINDOW_TYPE_UTILITY,
XATOM__NET_WORKAREA,
+ XATOM__GTK_WORKAREAS_D0,
XATOM__XEMBED,
XATOM__XEMBED_INFO,
XATOM_XdndAware,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index e6e61e801e..9ec4c7a98f 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -177,6 +177,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"_NET_WM_WINDOW_TYPE_NORMAL",
"_NET_WM_WINDOW_TYPE_UTILITY",
"_NET_WORKAREA",
+ "_GTK_WORKAREAS_D0",
"_XEMBED",
"_XEMBED_INFO",
"XdndAware",