window: Move X11 struts implementation to X11 codepath

This commit is contained in:
Jasper St. Pierre 2014-04-28 17:06:38 -04:00
parent 41235fcb86
commit 8b0747786a
3 changed files with 175 additions and 169 deletions

View File

@ -483,6 +483,7 @@ struct _MetaWindowClass
MetaRectangle constrained_rect, MetaRectangle constrained_rect,
MetaMoveResizeFlags flags, MetaMoveResizeFlags flags,
MetaMoveResizeResultFlags *result); MetaMoveResizeResultFlags *result);
gboolean (*update_struts) (MetaWindow *window);
void (*get_default_skip_hints) (MetaWindow *window, void (*get_default_skip_hints) (MetaWindow *window,
gboolean *skip_taskbar_out, gboolean *skip_taskbar_out,
gboolean *skip_pager_out); gboolean *skip_pager_out);

View File

@ -203,6 +203,12 @@ prefs_changed_callback (MetaPreference pref,
} }
} }
static gboolean
meta_window_real_update_struts (MetaWindow *window)
{
return FALSE;
}
static void static void
meta_window_real_get_default_skip_hints (MetaWindow *window, meta_window_real_get_default_skip_hints (MetaWindow *window,
gboolean *skip_taskbar_out, gboolean *skip_taskbar_out,
@ -368,6 +374,7 @@ meta_window_class_init (MetaWindowClass *klass)
object_class->get_property = meta_window_get_property; object_class->get_property = meta_window_get_property;
object_class->set_property = meta_window_set_property; object_class->set_property = meta_window_set_property;
klass->update_struts = meta_window_real_update_struts;
klass->get_default_skip_hints = meta_window_real_get_default_skip_hints; klass->get_default_skip_hints = meta_window_real_get_default_skip_hints;
g_object_class_install_property (object_class, g_object_class_install_property (object_class,
@ -5884,175 +5891,8 @@ invalidate_work_areas (MetaWindow *window)
void void
meta_window_update_struts (MetaWindow *window) meta_window_update_struts (MetaWindow *window)
{ {
GSList *old_struts; if (META_WINDOW_GET_CLASS (window)->update_struts (window))
GSList *new_struts;
GSList *old_iter, *new_iter;
gulong *struts = NULL;
int nitems;
gboolean changed;
g_return_if_fail (!window->override_redirect);
meta_verbose ("Updating struts for %s\n", window->desc);
old_struts = window->struts;
new_struts = NULL;
if (meta_prop_get_cardinal_list (window->display,
window->xwindow,
window->display->atom__NET_WM_STRUT_PARTIAL,
&struts, &nitems))
{
if (nitems != 12)
meta_verbose ("_NET_WM_STRUT_PARTIAL on %s has %d values instead "
"of 12\n",
window->desc, nitems);
else
{
/* Pull out the strut info for each side in the hint */
int i;
for (i=0; i<4; i++)
{
MetaStrut *temp;
int thickness, strut_begin, strut_end;
thickness = struts[i];
if (thickness == 0)
continue;
strut_begin = struts[4+(i*2)];
strut_end = struts[4+(i*2)+1];
temp = g_new (MetaStrut, 1);
temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */
temp->rect = window->screen->rect;
switch (temp->side)
{
case META_SIDE_RIGHT:
temp->rect.x = BOX_RIGHT(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_LEFT:
temp->rect.width = thickness;
temp->rect.y = strut_begin;
temp->rect.height = strut_end - strut_begin + 1;
break;
case META_SIDE_BOTTOM:
temp->rect.y = BOX_BOTTOM(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_TOP:
temp->rect.height = thickness;
temp->rect.x = strut_begin;
temp->rect.width = strut_end - strut_begin + 1;
break;
default:
g_assert_not_reached ();
}
new_struts = g_slist_prepend (new_struts, temp);
}
meta_verbose ("_NET_WM_STRUT_PARTIAL struts %lu %lu %lu %lu for "
"window %s\n",
struts[0], struts[1], struts[2], struts[3],
window->desc);
}
meta_XFree (struts);
}
else
{
meta_verbose ("No _NET_WM_STRUT property for %s\n",
window->desc);
}
if (!new_struts &&
meta_prop_get_cardinal_list (window->display,
window->xwindow,
window->display->atom__NET_WM_STRUT,
&struts, &nitems))
{
if (nitems != 4)
meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n",
window->desc, nitems);
else
{
/* Pull out the strut info for each side in the hint */
int i;
for (i=0; i<4; i++)
{
MetaStrut *temp;
int thickness;
thickness = struts[i];
if (thickness == 0)
continue;
temp = g_new (MetaStrut, 1);
temp->side = 1 << i;
temp->rect = window->screen->rect;
switch (temp->side)
{
case META_SIDE_RIGHT:
temp->rect.x = BOX_RIGHT(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_LEFT:
temp->rect.width = thickness;
break;
case META_SIDE_BOTTOM:
temp->rect.y = BOX_BOTTOM(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_TOP:
temp->rect.height = thickness;
break;
default:
g_assert_not_reached ();
}
new_struts = g_slist_prepend (new_struts, temp);
}
meta_verbose ("_NET_WM_STRUT struts %lu %lu %lu %lu for window %s\n",
struts[0], struts[1], struts[2], struts[3],
window->desc);
}
meta_XFree (struts);
}
else if (!new_struts)
{
meta_verbose ("No _NET_WM_STRUT property for %s\n",
window->desc);
}
/* Determine whether old_struts and new_struts are the same */
old_iter = old_struts;
new_iter = new_struts;
while (old_iter && new_iter)
{
MetaStrut *old_strut = (MetaStrut*) old_iter->data;
MetaStrut *new_strut = (MetaStrut*) new_iter->data;
if (old_strut->side != new_strut->side ||
!meta_rectangle_equal (&old_strut->rect, &new_strut->rect))
break;
old_iter = old_iter->next;
new_iter = new_iter->next;
}
changed = (old_iter != NULL || new_iter != NULL);
/* Update appropriately */
meta_free_gslist_and_elements (old_struts);
window->struts = new_struts;
if (changed)
{
meta_topic (META_DEBUG_WORKAREA,
"Invalidating work areas of window %s due to struts update\n",
window->desc);
invalidate_work_areas (window); invalidate_work_areas (window);
}
else
{
meta_topic (META_DEBUG_WORKAREA,
"Struts on %s were unchanged\n", window->desc);
}
} }
static void static void

View File

@ -40,6 +40,7 @@
#include <meta/meta-cursor-tracker.h> #include <meta/meta-cursor-tracker.h>
#include "frame.h" #include "frame.h"
#include "boxes-private.h"
#include "window-private.h" #include "window-private.h"
#include "window-props.h" #include "window-props.h"
#include "xprops.h" #include "xprops.h"
@ -898,6 +899,169 @@ meta_window_x11_move_resize_internal (MetaWindow *window,
*result |= META_MOVE_RESIZE_RESULT_RESIZED; *result |= META_MOVE_RESIZE_RESULT_RESIZED;
} }
static gboolean
meta_window_x11_update_struts (MetaWindow *window)
{
GSList *old_struts;
GSList *new_struts;
GSList *old_iter, *new_iter;
gulong *struts = NULL;
int nitems;
gboolean changed;
g_return_val_if_fail (!window->override_redirect, FALSE);
meta_verbose ("Updating struts for %s\n", window->desc);
old_struts = window->struts;
new_struts = NULL;
if (meta_prop_get_cardinal_list (window->display,
window->xwindow,
window->display->atom__NET_WM_STRUT_PARTIAL,
&struts, &nitems))
{
if (nitems != 12)
meta_verbose ("_NET_WM_STRUT_PARTIAL on %s has %d values instead "
"of 12\n",
window->desc, nitems);
else
{
/* Pull out the strut info for each side in the hint */
int i;
for (i=0; i<4; i++)
{
MetaStrut *temp;
int thickness, strut_begin, strut_end;
thickness = struts[i];
if (thickness == 0)
continue;
strut_begin = struts[4+(i*2)];
strut_end = struts[4+(i*2)+1];
temp = g_new (MetaStrut, 1);
temp->side = 1 << i; /* See MetaSide def. Matches nicely, eh? */
temp->rect = window->screen->rect;
switch (temp->side)
{
case META_SIDE_RIGHT:
temp->rect.x = BOX_RIGHT(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_LEFT:
temp->rect.width = thickness;
temp->rect.y = strut_begin;
temp->rect.height = strut_end - strut_begin + 1;
break;
case META_SIDE_BOTTOM:
temp->rect.y = BOX_BOTTOM(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_TOP:
temp->rect.height = thickness;
temp->rect.x = strut_begin;
temp->rect.width = strut_end - strut_begin + 1;
break;
default:
g_assert_not_reached ();
}
new_struts = g_slist_prepend (new_struts, temp);
}
meta_verbose ("_NET_WM_STRUT_PARTIAL struts %lu %lu %lu %lu for "
"window %s\n",
struts[0], struts[1], struts[2], struts[3],
window->desc);
}
meta_XFree (struts);
}
else
{
meta_verbose ("No _NET_WM_STRUT property for %s\n",
window->desc);
}
if (!new_struts &&
meta_prop_get_cardinal_list (window->display,
window->xwindow,
window->display->atom__NET_WM_STRUT,
&struts, &nitems))
{
if (nitems != 4)
meta_verbose ("_NET_WM_STRUT on %s has %d values instead of 4\n",
window->desc, nitems);
else
{
/* Pull out the strut info for each side in the hint */
int i;
for (i=0; i<4; i++)
{
MetaStrut *temp;
int thickness;
thickness = struts[i];
if (thickness == 0)
continue;
temp = g_new (MetaStrut, 1);
temp->side = 1 << i;
temp->rect = window->screen->rect;
switch (temp->side)
{
case META_SIDE_RIGHT:
temp->rect.x = BOX_RIGHT(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_LEFT:
temp->rect.width = thickness;
break;
case META_SIDE_BOTTOM:
temp->rect.y = BOX_BOTTOM(temp->rect) - thickness;
/* Intentionally fall through without breaking */
case META_SIDE_TOP:
temp->rect.height = thickness;
break;
default:
g_assert_not_reached ();
}
new_struts = g_slist_prepend (new_struts, temp);
}
meta_verbose ("_NET_WM_STRUT struts %lu %lu %lu %lu for window %s\n",
struts[0], struts[1], struts[2], struts[3],
window->desc);
}
meta_XFree (struts);
}
else if (!new_struts)
{
meta_verbose ("No _NET_WM_STRUT property for %s\n",
window->desc);
}
/* Determine whether old_struts and new_struts are the same */
old_iter = old_struts;
new_iter = new_struts;
while (old_iter && new_iter)
{
MetaStrut *old_strut = (MetaStrut*) old_iter->data;
MetaStrut *new_strut = (MetaStrut*) new_iter->data;
if (old_strut->side != new_strut->side ||
!meta_rectangle_equal (&old_strut->rect, &new_strut->rect))
break;
old_iter = old_iter->next;
new_iter = new_iter->next;
}
changed = (old_iter != NULL || new_iter != NULL);
/* Update appropriately */
meta_free_gslist_and_elements (old_struts);
window->struts = new_struts;
return changed;
}
static void static void
meta_window_x11_get_default_skip_hints (MetaWindow *window, meta_window_x11_get_default_skip_hints (MetaWindow *window,
gboolean *skip_taskbar_out, gboolean *skip_taskbar_out,
@ -922,6 +1086,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
window_class->kill = meta_window_x11_kill; window_class->kill = meta_window_x11_kill;
window_class->focus = meta_window_x11_focus; window_class->focus = meta_window_x11_focus;
window_class->move_resize_internal = meta_window_x11_move_resize_internal; window_class->move_resize_internal = meta_window_x11_move_resize_internal;
window_class->update_struts = meta_window_x11_update_struts;
window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints;
} }