diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2018-06-15 01:52:08 +0300 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2018-06-15 01:52:08 +0300 |
commit | f4aa7eaee6078360b5409f56bb6e9a4dbabc12d9 (patch) | |
tree | 10efceca9177b076bc9d917a3a1b940bb9753ebc | |
parent | 31904dd05d1d84b633a410cea5ae0ae9244d637e (diff) | |
download | gtk+-wip/muktupavels/work-areas-3-22.tar.gz |
x11: use per-monitor work areaswip/muktupavels/work-areas-3-22
If window manager supports _NET_WORKAREA_Mn use per-monitor work
area.
-rw-r--r-- | gdk/x11/gdkmonitor-x11.c | 33 | ||||
-rw-r--r-- | gdk/x11/gdkscreen-x11.c | 76 | ||||
-rw-r--r-- | gdk/x11/gdkscreen-x11.h | 3 |
3 files changed, 101 insertions, 11 deletions
diff --git a/gdk/x11/gdkmonitor-x11.c b/gdk/x11/gdkmonitor-x11.c index 899511afcd..21a6da6fe9 100644 --- a/gdk/x11/gdkmonitor-x11.c +++ b/gdk/x11/gdkmonitor-x11.c @@ -66,18 +66,29 @@ 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)) - *dest = workarea; + if (!gdk_monitor_has_fullscreen_window (monitor)) + { + if (gdk_rectangle_intersect (dest, &workarea, &workarea)) + *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; + } } } diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index 43da96b45f..5ead4e129b 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -300,6 +300,82 @@ out: return FALSE; } +static int +get_monitor_num (GdkScreen *screen, + GdkMonitor *monitor) +{ +#ifdef HAVE_XFREE_XINERAMA + GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); + XineramaScreenInfo *x_monitors; + int x_n_monitors; + GdkRectangle geometry; + int monitor_num; + int i; + + if (!XineramaIsActive (x11_screen->xdisplay)) + return -1; + + x_monitors = XineramaQueryScreens (x11_screen->xdisplay, &x_n_monitors); + if (x_n_monitors <= 0 || x_monitors == NULL) + { + if (x_monitors) + XFree (x_monitors); + + return -1; + } + + gdk_monitor_get_geometry (monitor, &geometry); + monitor_num = -1; + + for (i = 0; i < x_n_monitors; i++) + { + if (x_monitors[i].x_org != geometry.x || + x_monitors[i].y_org != geometry.y || + x_monitors[i].width != geometry.width || + x_monitors[i].height != geometry.height) + continue; + + monitor_num = i; + break; + } + + XFree (x_monitors); + return monitor_num; +#else + return -1; +#endif +} + +gboolean +_gdk_x11_screen_get_monitor_work_area (GdkScreen *screen, + GdkMonitor *monitor, + GdkRectangle *area) +{ + Display *display; + int monitor_num; + gchar *workarea_name; + Atom workarea; + + display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen)); + + if (!gdk_x11_screen_supports_net_wm_hint (screen, + gdk_atom_intern_static_string ("_NET_WORKAREA_Mn"))) + return FALSE; + + monitor_num = get_monitor_num (screen, monitor); + if (monitor_num < 0) + return FALSE; + + workarea_name = g_strdup_printf ("_NET_WORKAREA_M%d", monitor_num); + workarea = XInternAtom (display, workarea_name, True); + g_free (workarea_name); + + if (workarea == None) + return FALSE; + + return get_work_area (screen, workarea, area); +} + void gdk_x11_screen_get_work_area (GdkScreen *screen, GdkRectangle *area) diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h index aca9b3c9e0..19edf2aa12 100644 --- a/gdk/x11/gdkscreen-x11.h +++ b/gdk/x11/gdkscreen-x11.h @@ -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); |