forked from AuroraMiddleware/gtk
x11: add support for _GTK_WORKAREAS_Dn
If window manager supports _GTK_WORKAREAS use per-monitor work areas. https://mail.gnome.org/archives/wm-spec-list/2018-December/msg00000.html https://gitlab.freedesktop.org/xdg/xdg-specs/merge_requests/22 https://gitlab.gnome.org/GNOME/gtk/merge_requests/478
This commit is contained in:
parent
cb1c16021e
commit
6609a9f061
@ -66,19 +66,27 @@ gdk_x11_monitor_get_workarea (GdkMonitor *monitor,
|
||||
|
||||
gdk_monitor_get_geometry (monitor, dest);
|
||||
|
||||
/* The EWMH constrains workarea to be a rectangle, so it
|
||||
* can't adequately deal with L-shaped monitor arrangements.
|
||||
* As a workaround, we ignore the workarea for anything
|
||||
* but the primary monitor. Since that is where the 'desktop
|
||||
* chrome' usually lives, this works ok in practice.
|
||||
*/
|
||||
if (gdk_monitor_is_primary (monitor) &&
|
||||
!gdk_monitor_has_fullscreen_window (monitor))
|
||||
if (_gdk_x11_screen_get_monitor_work_area (screen, monitor, &workarea))
|
||||
{
|
||||
gdk_x11_screen_get_work_area (screen, &workarea);
|
||||
if (gdk_rectangle_intersect (dest, &workarea, &workarea))
|
||||
if (!gdk_monitor_has_fullscreen_window (monitor))
|
||||
*dest = workarea;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The EWMH constrains workarea to be a rectangle, so it
|
||||
* can't adequately deal with L-shaped monitor arrangements.
|
||||
* As a workaround, we ignore the workarea for anything
|
||||
* but the primary monitor. Since that is where the 'desktop
|
||||
* chrome' usually lives, this works ok in practice.
|
||||
*/
|
||||
if (gdk_monitor_is_primary (monitor) &&
|
||||
!gdk_monitor_has_fullscreen_window (monitor))
|
||||
{
|
||||
gdk_x11_screen_get_work_area (screen, &workarea);
|
||||
if (gdk_rectangle_intersect (dest, &workarea, &workarea))
|
||||
*dest = workarea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -234,6 +234,106 @@ get_current_desktop (GdkScreen *screen)
|
||||
return workspace;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_x11_screen_get_monitor_work_area (GdkScreen *screen,
|
||||
GdkMonitor *monitor,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
GdkX11Screen *x11_screen;
|
||||
GdkAtom net_workareas;
|
||||
GdkDisplay *display;
|
||||
Display *xdisplay;
|
||||
int current_desktop;
|
||||
char *workareas_dn_name;
|
||||
Atom workareas_dn;
|
||||
int screen_number;
|
||||
Window xroot;
|
||||
int result;
|
||||
Atom type;
|
||||
int format;
|
||||
gulong num;
|
||||
gulong leftovers;
|
||||
guchar *ret_workarea;
|
||||
long *workareas;
|
||||
GdkRectangle geometry;
|
||||
int i;
|
||||
|
||||
x11_screen = GDK_X11_SCREEN (screen);
|
||||
|
||||
net_workareas = gdk_atom_intern_static_string ("_GTK_WORKAREAS");
|
||||
if (!gdk_x11_screen_supports_net_wm_hint (screen, net_workareas))
|
||||
return FALSE;
|
||||
|
||||
display = gdk_screen_get_display (screen);
|
||||
xdisplay = gdk_x11_display_get_xdisplay (display);
|
||||
|
||||
current_desktop = get_current_desktop (screen);
|
||||
workareas_dn_name = g_strdup_printf ("_GTK_WORKAREAS_D%d", current_desktop);
|
||||
workareas_dn = XInternAtom (xdisplay, workareas_dn_name, True);
|
||||
g_free (workareas_dn_name);
|
||||
|
||||
if (workareas_dn == None)
|
||||
return FALSE;
|
||||
|
||||
screen_number = gdk_x11_screen_get_screen_number (screen);
|
||||
xroot = XRootWindow (xdisplay, screen_number);
|
||||
|
||||
gdk_x11_display_error_trap_push (display);
|
||||
|
||||
ret_workarea = NULL;
|
||||
result = XGetWindowProperty (xdisplay,
|
||||
xroot,
|
||||
workareas_dn,
|
||||
0,
|
||||
G_MAXLONG,
|
||||
False,
|
||||
AnyPropertyType,
|
||||
&type,
|
||||
&format,
|
||||
&num,
|
||||
&leftovers,
|
||||
&ret_workarea);
|
||||
|
||||
gdk_x11_display_error_trap_pop_ignored (display);
|
||||
|
||||
if (result != Success ||
|
||||
type == None ||
|
||||
format == 0 ||
|
||||
leftovers ||
|
||||
num % 4 != 0)
|
||||
{
|
||||
XFree (ret_workarea);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
workareas = (long *) ret_workarea;
|
||||
|
||||
gdk_monitor_get_geometry (monitor, &geometry);
|
||||
*area = geometry;
|
||||
|
||||
for (i = 0; i < num / 4; i++)
|
||||
{
|
||||
GdkRectangle work_area;
|
||||
|
||||
work_area = (GdkRectangle) {
|
||||
.x = workareas[0] / x11_screen->window_scale,
|
||||
.y = workareas[1] / x11_screen->window_scale,
|
||||
.width = workareas[2] / x11_screen->window_scale,
|
||||
.height = workareas[3] / x11_screen->window_scale,
|
||||
};
|
||||
|
||||
if (gdk_rectangle_intersect (area, &work_area, &work_area))
|
||||
*area = work_area;
|
||||
|
||||
workareas += 4;
|
||||
}
|
||||
|
||||
XFree (ret_workarea);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_x11_screen_get_work_area (GdkScreen *screen,
|
||||
GdkRectangle *area)
|
||||
|
@ -119,6 +119,9 @@ void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
|
||||
gint *right);
|
||||
void _gdk_x11_screen_set_window_scale (GdkX11Screen *x11_screen,
|
||||
int scale);
|
||||
gboolean _gdk_x11_screen_get_monitor_work_area (GdkScreen *screen,
|
||||
GdkMonitor *monitor,
|
||||
GdkRectangle *area);
|
||||
void gdk_x11_screen_get_work_area (GdkScreen *screen,
|
||||
GdkRectangle *area);
|
||||
gint gdk_x11_screen_get_width (GdkScreen *screen);
|
||||
|
Loading…
Reference in New Issue
Block a user