summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2018-06-15 01:52:08 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2018-06-15 01:52:08 +0300
commitf4aa7eaee6078360b5409f56bb6e9a4dbabc12d9 (patch)
tree10efceca9177b076bc9d917a3a1b940bb9753ebc
parent31904dd05d1d84b633a410cea5ae0ae9244d637e (diff)
downloadgtk+-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.c33
-rw-r--r--gdk/x11/gdkscreen-x11.c76
-rw-r--r--gdk/x11/gdkscreen-x11.h3
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);