diff --git a/src/core/window-private.h b/src/core/window-private.h index 017f01be6..1e38586b1 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -483,6 +483,7 @@ struct _MetaWindowClass MetaRectangle constrained_rect, MetaMoveResizeFlags flags, MetaMoveResizeResultFlags *result); + gboolean (*update_struts) (MetaWindow *window); void (*get_default_skip_hints) (MetaWindow *window, gboolean *skip_taskbar_out, gboolean *skip_pager_out); diff --git a/src/core/window.c b/src/core/window.c index 22f768b6d..3eff727ad 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -203,6 +203,12 @@ prefs_changed_callback (MetaPreference pref, } } +static gboolean +meta_window_real_update_struts (MetaWindow *window) +{ + return FALSE; +} + static void meta_window_real_get_default_skip_hints (MetaWindow *window, gboolean *skip_taskbar_out, @@ -368,6 +374,7 @@ meta_window_class_init (MetaWindowClass *klass) object_class->get_property = meta_window_get_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; g_object_class_install_property (object_class, @@ -5884,175 +5891,8 @@ invalidate_work_areas (MetaWindow *window) void meta_window_update_struts (MetaWindow *window) { - GSList *old_struts; - 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); - } - else - { - meta_topic (META_DEBUG_WORKAREA, - "Struts on %s were unchanged\n", window->desc); - } + if (META_WINDOW_GET_CLASS (window)->update_struts (window)) + invalidate_work_areas (window); } static void diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index db2a7d623..422447ed1 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -40,6 +40,7 @@ #include #include "frame.h" +#include "boxes-private.h" #include "window-private.h" #include "window-props.h" #include "xprops.h" @@ -898,6 +899,169 @@ meta_window_x11_move_resize_internal (MetaWindow *window, *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 meta_window_x11_get_default_skip_hints (MetaWindow *window, gboolean *skip_taskbar_out, @@ -922,6 +1086,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->kill = meta_window_x11_kill; window_class->focus = meta_window_x11_focus; 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; }