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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2020-06-30 17:56:53 +08:00 committed by Alexandre Julliard
parent 5dd03cbc8f
commit 59c206f9dc
3 changed files with 30 additions and 1 deletions

View File

@ -263,10 +263,37 @@ RECT get_work_area(const RECT *monitor_rect)
{ {
Atom type; Atom type;
int format; int format;
unsigned long count, remaining; unsigned long count, remaining, i;
long *work_area; long *work_area;
RECT work_rect; 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), if (!XGetWindowProperty(gdi_display, DefaultRootWindow(gdi_display), x11drv_atom(_NET_WORKAREA),
0, ~0, False, XA_CARDINAL, &type, &format, &count, &remaining, 0, ~0, False, XA_CARDINAL, &type, &format, &count, &remaining,
(unsigned char **)&work_area)) (unsigned char **)&work_area))

View File

@ -464,6 +464,7 @@ enum x11drv_atoms
XATOM__NET_WM_WINDOW_TYPE_NORMAL, XATOM__NET_WM_WINDOW_TYPE_NORMAL,
XATOM__NET_WM_WINDOW_TYPE_UTILITY, XATOM__NET_WM_WINDOW_TYPE_UTILITY,
XATOM__NET_WORKAREA, XATOM__NET_WORKAREA,
XATOM__GTK_WORKAREAS_D0,
XATOM__XEMBED, XATOM__XEMBED,
XATOM__XEMBED_INFO, XATOM__XEMBED_INFO,
XATOM_XdndAware, XATOM_XdndAware,

View File

@ -177,6 +177,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"_NET_WM_WINDOW_TYPE_NORMAL", "_NET_WM_WINDOW_TYPE_NORMAL",
"_NET_WM_WINDOW_TYPE_UTILITY", "_NET_WM_WINDOW_TYPE_UTILITY",
"_NET_WORKAREA", "_NET_WORKAREA",
"_GTK_WORKAREAS_D0",
"_XEMBED", "_XEMBED",
"_XEMBED_INFO", "_XEMBED_INFO",
"XdndAware", "XdndAware",