summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorraveit65 <[email protected]>2021-04-10 16:37:40 +0200
committerraveit65 <[email protected]>2021-06-07 20:09:03 +0200
commit3ed0ddb242a4804cd7fcfcfcf39a47766eaa816d (patch)
treeb11f566e6c4f90db6a1868c834c6d84ca5dd15a7 /src/core
parent4e4fd6c512423b16640914b33192a32f290b0ef1 (diff)
downloadmarco-3ed0ddb242a4804cd7fcfcfcf39a47766eaa816d.tar.bz2
marco-3ed0ddb242a4804cd7fcfcfcf39a47766eaa816d.tar.xz
window: add support for _GNOME_WM_STRUT_AREA
In addition to existing properties use also new _GNOME_WM_STRUT_AREA property that allows creating struts between monitors. https://mail.gnome.org/archives/wm-spec-list/2018-December/msg00000.html https://gitlab.freedesktop.org/xdg/xdg-specs/merge_requests/22 origin commit: https://gitlab.gnome.org/GNOME/metacity/commit/922de13
Diffstat (limited to 'src/core')
-rw-r--r--src/core/atomnames.h1
-rw-r--r--src/core/boxes.c22
-rw-r--r--src/core/testboxes.c6
-rw-r--r--src/core/window-props.c1
-rw-r--r--src/core/window.c88
-rw-r--r--src/core/workspace.c6
6 files changed, 119 insertions, 5 deletions
diff --git a/src/core/atomnames.h b/src/core/atomnames.h
index 059594d3..cea869d0 100644
--- a/src/core/atomnames.h
+++ b/src/core/atomnames.h
@@ -65,6 +65,7 @@ item(_GTK_WORKAREAS)
item(_MATE_PANEL_ACTION)
item(_MATE_PANEL_ACTION_MAIN_MENU)
item(_MATE_PANEL_ACTION_RUN_DIALOG)
+item(_GNOME_WM_STRUT_AREA)
item(_MARCO_SENTINEL)
item(_MARCO_VERSION)
item(WM_CLIENT_MACHINE)
diff --git a/src/core/boxes.c b/src/core/boxes.c
index 49c82ccc..a9006ede 100644
--- a/src/core/boxes.c
+++ b/src/core/boxes.c
@@ -522,7 +522,9 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
GList*
meta_rectangle_get_minimal_spanning_set_for_region (
const MetaRectangle *basic_rect,
- const GSList *all_struts)
+ const GSList *all_struts,
+ gboolean skip_middle_struts)
+
{
/* NOTE FOR OPTIMIZERS: This function *might* be somewhat slow,
* especially due to the call to merge_spanning_rects_in_region() (which
@@ -583,7 +585,23 @@ meta_rectangle_get_minimal_spanning_set_for_region (
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
{
GList *rect_iter;
- MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
+ MetaStrut *strut = (MetaStrut *) strut_iter->data;
+ MetaRectangle *strut_rect = &strut->rect;
+
+ if (skip_middle_struts && strut->edge == META_EDGE_XINERAMA)
+ {
+ if ((strut->side == META_SIDE_LEFT &&
+ strut_rect->x != basic_rect->x) ||
+ (strut->side == META_SIDE_RIGHT &&
+ strut_rect->x + strut_rect->width != basic_rect->width) ||
+ (strut->side == META_SIDE_TOP &&
+ strut_rect->y != basic_rect->y) ||
+ (strut->side == META_SIDE_BOTTOM &&
+ strut_rect->y + strut_rect->height != basic_rect->height))
+ {
+ continue;
+ }
+ }
tmp_list = ret;
ret = NULL;
diff --git a/src/core/testboxes.c b/src/core/testboxes.c
index fecca881..ecf35f2f 100644
--- a/src/core/testboxes.c
+++ b/src/core/testboxes.c
@@ -66,6 +66,7 @@ new_meta_strut (int x, int y, int width, int height, int side)
temporary = g_new (MetaStrut, 1);
temporary->rect = meta_rect(x, y, width, height);
temporary->side = side;
+ temporary->edge = META_EDGE_SCREEN;
return temporary;
}
@@ -294,7 +295,10 @@ get_screen_region (int which)
ret = NULL;
struts = get_strut_list (which);
- ret = meta_rectangle_get_minimal_spanning_set_for_region (&basic_rect, struts);
+ ret = meta_rectangle_get_minimal_spanning_set_for_region (&basic_rect,
+ struts,
+ FALSE);
+
free_strut_list (struts);
return ret;
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 2004c6a0..fb8ac4c1 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -1593,6 +1593,7 @@ meta_display_init_window_prop_hooks (MetaDisplay *display)
{ display->atom__NET_WM_DESKTOP, META_PROP_VALUE_CARDINAL, reload_net_wm_desktop },
{ display->atom__NET_WM_STRUT, META_PROP_VALUE_INVALID, reload_struts },
{ display->atom__NET_WM_STRUT_PARTIAL, META_PROP_VALUE_INVALID, reload_struts },
+ { display->atom__GNOME_WM_STRUT_AREA, META_PROP_VALUE_INVALID, reload_struts },
{ display->atom__NET_STARTUP_ID, META_PROP_VALUE_UTF8, reload_net_startup_id },
{ display->atom__NET_WM_SYNC_REQUEST_COUNTER, META_PROP_VALUE_SYNC_COUNTER, reload_update_counter },
{ XA_WM_NORMAL_HINTS, META_PROP_VALUE_SIZE_HINTS, reload_normal_hints },
diff --git a/src/core/window.c b/src/core/window.c
index add00789..55badf54 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6240,6 +6240,91 @@ meta_window_update_struts (MetaWindow *window)
if (meta_prop_get_cardinal_list (window->display,
window->xwindow,
+ window->display->atom__GNOME_WM_STRUT_AREA,
+ &struts, &nitems))
+ {
+ if (nitems != 4)
+ {
+ meta_verbose ("_GNOME_WM_STRUT_AREA on %s has %d values instead of 4\n",
+ window->desc, nitems);
+ }
+ else
+ {
+ MetaStrut *temp;
+ MetaSide side;
+ gboolean valid;
+ int i;
+
+ temp = g_new (MetaStrut, 1);
+
+ temp->rect.x = struts[0];
+ temp->rect.y = struts[1];
+ temp->rect.width = struts[2];
+ temp->rect.height = struts[3];
+
+ side = META_SIDE_LEFT;
+ valid = FALSE;
+
+ for (i = 0; i < window->screen->n_xinerama_infos; i++)
+ {
+ MetaRectangle monitor;
+
+ monitor = window->screen->xinerama_infos[i].rect;
+ if (!meta_rectangle_contains_rect (&monitor, &temp->rect))
+ continue;
+
+ if (temp->rect.height > temp->rect.width)
+ {
+ if (temp->rect.x == monitor.x)
+ {
+ side = META_SIDE_LEFT;
+ valid = TRUE;
+ }
+ else if (temp->rect.x + temp->rect.width == monitor.x + monitor.width)
+ {
+ side = META_SIDE_RIGHT;
+ valid = TRUE;
+ }
+ }
+ else
+ {
+ if (temp->rect.y == monitor.y)
+ {
+ side = META_SIDE_TOP;
+ valid = TRUE;
+ }
+ else if (temp->rect.y + temp->rect.height == monitor.y + monitor.height)
+ {
+ side = META_SIDE_BOTTOM;
+ valid = TRUE;
+ }
+ }
+ }
+
+ if (valid)
+ {
+ temp->side = side;
+ temp->edge = META_EDGE_XINERAMA;
+
+ new_struts = g_slist_prepend (new_struts, temp);
+ }
+ else
+ {
+ g_free (temp);
+ }
+ }
+
+ meta_XFree (struts);
+ }
+ else
+ {
+ meta_verbose ("No _GNOME_WM_STRUT_AREA property for %s\n",
+ window->desc);
+ }
+
+ if (!new_struts &&
+ meta_prop_get_cardinal_list (window->display,
+ window->xwindow,
window->display->atom__NET_WM_STRUT_PARTIAL,
&struts, &nitems))
{
@@ -6264,6 +6349,7 @@ meta_window_update_struts (MetaWindow *window)
temp = g_new (MetaStrut, 1);
temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */
+ temp->edge = META_EDGE_SCREEN;
temp->rect = window->screen->rect;
switch (temp->side)
{
@@ -6327,6 +6413,7 @@ meta_window_update_struts (MetaWindow *window)
temp = g_new (MetaStrut, 1);
temp->side = 1 << i;
+ temp->edge = META_EDGE_SCREEN;
temp->rect = window->screen->rect;
switch (temp->side)
{
@@ -6370,6 +6457,7 @@ meta_window_update_struts (MetaWindow *window)
MetaStrut *new_strut = (MetaStrut*) new_iter->data;
if (old_strut->side != new_strut->side ||
+ old_strut->edge != new_strut->edge ||
!meta_rectangle_equal (&old_strut->rect, &new_strut->rect))
break;
diff --git a/src/core/workspace.c b/src/core/workspace.c
index 620184f9..ce6080ba 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -635,12 +635,14 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
workspace->xinerama_region[i] =
meta_rectangle_get_minimal_spanning_set_for_region (
&workspace->screen->xinerama_infos[i].rect,
- workspace->all_struts);
+ workspace->all_struts,
+ FALSE);
}
workspace->screen_region =
meta_rectangle_get_minimal_spanning_set_for_region (
&workspace->screen->rect,
- workspace->all_struts);
+ workspace->all_struts,
+ TRUE);
/* STEP 3: Get the work areas (region-to-maximize-to) for the screen and
* xineramas.