diff options
author | Sam Spilsbury <sam.spilsbury@canonical.com> | 2011-02-01 17:26:11 +0800 |
---|---|---|
committer | Sam Spilsbury <sam.spilsbury@canonical.com> | 2011-02-01 17:26:11 +0800 |
commit | 4ae95852e53075caed1558620127f0c1405fe474 (patch) | |
tree | 12396907cfded0311fa4afc7064d3afc9b7a9241 | |
parent | eda4ce59d1010289f1cdd62e4ce03a3517dd61da (diff) | |
download | compiz-with-glib-mainloop-4ae95852e53075caed1558620127f0c1405fe474.tar.gz compiz-with-glib-mainloop-4ae95852e53075caed1558620127f0c1405fe474.tar.bz2 |
Allow semantic difference between frame window geometry and frame size.
Rationale: some window decorators or themes might want to specify a border
input area that is slightly larger than the visible borders on screen
(eg for enhanced resize handles, a11y purposes, etc) or the theme might
want to specify some additional decoration which should affect placement
but should not be interacted with.
In this case we have a priv->border and priv->input window property.
priv->border specifies the actual semantic size of the window decoration
that should affect placement and priv->input specifies the extents of
the frame window past the client.
Fixes LP: #710271
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | gtk/window-decorator/decorator.c | 3 | ||||
-rw-r--r-- | gtk/window-decorator/decorprops.c | 3 | ||||
-rw-r--r-- | gtk/window-decorator/metacity.c | 3 | ||||
-rw-r--r-- | include/core/core.h | 2 | ||||
-rw-r--r-- | include/core/window.h | 3 | ||||
-rw-r--r-- | include/decoration.h | 10 | ||||
-rw-r--r-- | kde/window-decorator-kde4/decorator.cpp | 2 | ||||
-rw-r--r-- | kde/window-decorator-kde4/switcher.cpp | 4 | ||||
-rw-r--r-- | kde/window-decorator-kde4/window.cpp | 3 | ||||
-rw-r--r-- | libdecoration/decoration.c | 120 | ||||
-rw-r--r-- | plugins/decor/src/decor.cpp | 78 | ||||
-rw-r--r-- | plugins/decor/src/decor.h | 6 | ||||
-rw-r--r-- | src/privatewindow.h | 1 | ||||
-rw-r--r-- | src/window.cpp | 21 |
15 files changed, 179 insertions, 82 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 75e7109..df4a432 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ set (COMPIZ_VERSION_MICRO 2) set (COMPIZ_VERSION_MACRO 1) set (VERSION ${COMPIZ_VERSION_MAJOR}.${COMPIZ_VERSION_MINOR}.${COMPIZ_VERSION_MICRO}.${COMPIZ_VERSION_MACRO}) -set (DECOR_INTERFACE_VERSION 20080901) +set (DECOR_INTERFACE_VERSION 20110130) if (COMPIZ_PACKAGING_ENABLED) set (prefix ${CMAKE_INSTALL_PREFIX} CACHE PATH "prefix") diff --git a/gtk/window-decorator/decorator.c b/gtk/window-decorator/decorator.c index 68eb22f..3bcaddd 100644 --- a/gtk/window-decorator/decorator.c +++ b/gtk/window-decorator/decorator.c @@ -748,6 +748,7 @@ update_default_decorations (GdkScreen *screen) decor_quads_to_property (data, no_border_shadow->pixmap, &_shadow_extents, &_shadow_extents, + &_shadow_extents, &_shadow_extents, 0, 0, quads, nQuad); XChangeProperty (xdisplay, xroot, @@ -820,6 +821,7 @@ update_default_decorations (GdkScreen *screen) XRenderFreePicture (xdisplay, d.picture); decor_quads_to_property (data, GDK_PIXMAP_XID (d.pixmap), + &extents, &extents, &extents, &extents, 0, 0, quads, nQuad); XChangeProperty (xdisplay, xroot, @@ -847,6 +849,7 @@ update_default_decorations (GdkScreen *screen) XRenderFreePicture (xdisplay, d.picture); decor_quads_to_property (data, GDK_PIXMAP_XID (d.pixmap), + &extents, &extents, &extents, &extents, 0, 0, quads, nQuad); XChangeProperty (xdisplay, xroot, diff --git a/gtk/window-decorator/decorprops.c b/gtk/window-decorator/decorprops.c index 68b6ed5..b6b3820 100644 --- a/gtk/window-decorator/decorprops.c +++ b/gtk/window-decorator/decorprops.c @@ -36,7 +36,7 @@ decor_update_window_property (decor_t *d) else { decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap), - &extents, &extents, + &extents, &extents, &extents, &extents, ICON_SPACE + d->button_width, 0, quads, nQuad); @@ -111,6 +111,7 @@ decor_update_switcher_property (decor_t *d) decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap), &_switcher_extents, &_switcher_extents, + &_switcher_extents, &_switcher_extents, 0, 0, quads, nQuad); style = gtk_widget_get_style (style_window_rgba); diff --git a/gtk/window-decorator/metacity.c b/gtk/window-decorator/metacity.c index bbef354..204b608 100644 --- a/gtk/window-decorator/metacity.c +++ b/gtk/window-decorator/metacity.c @@ -69,7 +69,8 @@ decor_update_meta_window_property (decor_t *d, decor_gen_window_property (data, &extents, &max_extents, 20, 20); else decor_quads_to_property (data, GDK_PIXMAP_XID (d->pixmap), - &extents, &max_extents, + &extents, &extents, + &max_extents, &max_extents, ICON_SPACE + d->button_width, 0, quads, nQuad); diff --git a/include/core/core.h b/include/core/core.h index 0e677d1..5da8dd4 100644 --- a/include/core/core.h +++ b/include/core/core.h @@ -26,7 +26,7 @@ #ifndef _COMPIZ_CORE_H #define _COMPIZ_CORE_H -#define CORE_ABIVERSION 20110126 +#define CORE_ABIVERSION 20110131 #include <stdio.h> #include <assert.h> diff --git a/include/core/window.h b/include/core/window.h index aa7fbde..a6e4b4a 100644 --- a/include/core/window.h +++ b/include/core/window.h @@ -343,7 +343,8 @@ class CompWindow : const CompRegion & frameRegion () const; void updateFrameRegion (); - void setWindowFrameExtents (CompWindowExtents *input); + void setWindowFrameExtents (CompWindowExtents *border, + CompWindowExtents *frame = NULL); unsigned int & wmType (); diff --git a/include/decoration.h b/include/decoration.h index 8e26e85..b0c731b 100644 --- a/include/decoration.h +++ b/include/decoration.h @@ -175,7 +175,7 @@ typedef void (*decor_draw_func_t) (Display *xdisplay, void *closure); #define WINDOW_PROP_SIZE 12 -#define BASE_PROP_SIZE 13 +#define BASE_PROP_SIZE 21 #define QUAD_PROP_SIZE 9 #define N_QUADS_MAX 24 @@ -185,7 +185,9 @@ decor_version (void); void decor_quads_to_property (long *data, Pixmap pixmap, + decor_extents_t *frame_input, decor_extents_t *input, + decor_extents_t *frame_max_input, decor_extents_t *max_input, int min_width, int min_height, @@ -209,8 +211,10 @@ int decor_pixmap_property_to_quads (long *data, int size, Pixmap *pixmap, - decor_extents_t *input, - decor_extents_t *max_input, + decor_extents_t *frame_input, + decor_extents_t *input, + decor_extents_t *frame_max_input, + decor_extents_t *max_input, int *min_width, int *min_height, decor_quad_t *quad); diff --git a/kde/window-decorator-kde4/decorator.cpp b/kde/window-decorator-kde4/decorator.cpp index 40fa0ee..76ea414 100644 --- a/kde/window-decorator-kde4/decorator.cpp +++ b/kde/window-decorator-kde4/decorator.cpp @@ -277,7 +277,7 @@ KWD::Decorator::updateShadow (void) nQuad = decor_set_lSrStSbS_window_quads (quads, &context, &layout); decor_quads_to_property (data, mNoBorderShadow->pixmap, - &extents, &extents, + &extents, &extents, &extents, &extents, 0, 0, quads, nQuad); KWD::trapXError (); diff --git a/kde/window-decorator-kde4/switcher.cpp b/kde/window-decorator-kde4/switcher.cpp index 9cf77ca..201457d 100644 --- a/kde/window-decorator-kde4/switcher.cpp +++ b/kde/window-decorator-kde4/switcher.cpp @@ -232,12 +232,12 @@ KWD::Switcher::updateWindowProperties () lh / 2, rh / 2, w, w / 2); #ifdef QT_45 decor_quads_to_property (data, mX11Pixmap, - &mBorder, &mBorder, + &mBorder, &mBorder, &mBorder, &mBorder, 0, 0, quads, nQuad); #else decor_quads_to_property (data, mPixmap.handle (), - &mBorder, &mBorder, + &mBorder, &mBorder, &mBorder, &mBorder, 0, 0, quads, nQuad); #endif diff --git a/kde/window-decorator-kde4/window.cpp b/kde/window-decorator-kde4/window.cpp index 57848f8..bd89e92 100644 --- a/kde/window-decorator-kde4/window.cpp +++ b/kde/window-decorator-kde4/window.cpp @@ -1237,7 +1237,8 @@ KWD::Window::updateProperty (void) q += n; nQuad += n; } - decor_quads_to_property (data, mPixmap, &mBorder, &maxExtents, + decor_quads_to_property (data, mPixmap, &mBorder, &mBorder, + &maxExtents, &maxExtents, 1, 0, quads, nQuad); } else diff --git a/libdecoration/decoration.c b/libdecoration/decoration.c index 834ecd9..6042d98 100644 --- a/libdecoration/decoration.c +++ b/libdecoration/decoration.c @@ -67,18 +67,32 @@ decor_version (void) data[2] = pixmap - data[3] = input left - data[4] = input right - data[5] = input top - data[6] = input bottom - - data[7] = input left when maximized - data[8] = input right when maximized - data[9] = input top when maximized - data[10] = input bottom when maximized - - data[11] = min width - data[12] = min height + extents + + frame input is used for creating the input area of + the frame window which the client will be + reparented into, border is used for positioning + + data[3] = frame left + data[4] = frame right + data[5] = frame top + data[6] = frame bottom + data[7] = input left + data[8] = input right + data[9] = input top + data[10] = input bottom + + data[11] = frame left when maximized + data[12] = frame right when maximized + data[13] = frame top when maximized + data[14] = frame bottom when maximized + data[15] = border left when maximized + data[16] = border right when maximized + data[17] = border top when maximized + data[18] = border bottom when maximized + + data[19] = min width + data[20] = min height flags @@ -86,21 +100,23 @@ decor_version (void) 9rd and 10th bit alignment, 11rd and 12th bit clamp, 13th bit XX, 14th bit XY, 15th bit YX, 16th bit YY. - data[12 + n * 9 + 1] = flags - data[12 + n * 9 + 2] = p1 x - data[12 + n * 9 + 3] = p1 y - data[12 + n * 9 + 4] = p2 x - data[12 + n * 9 + 5] = p2 y - data[12 + n * 9 + 6] = widthMax - data[12 + n * 9 + 7] = heightMax - data[12 + n * 9 + 8] = x0 - data[12 + n * 9 + 9] = y0 + data[18 + n * 9 + 1] = flags + data[18 + n * 9 + 2] = p1 x + data[18 + n * 9 + 3] = p1 y + data[18 + n * 9 + 4] = p2 x + data[18 + n * 9 + 5] = p2 y + data[18 + n * 9 + 6] = widthMax + data[18 + n * 9 + 7] = heightMax + data[18 + n * 9 + 8] = x0 + data[18 + n * 9 + 9] = y0 */ void decor_quads_to_property (long *data, Pixmap pixmap, - decor_extents_t *input, - decor_extents_t *max_input, + decor_extents_t *frame, + decor_extents_t *border, + decor_extents_t *max_frame, + decor_extents_t *max_border, int min_width, int min_height, decor_quad_t *quad, @@ -111,15 +127,23 @@ decor_quads_to_property (long *data, memcpy (data++, &pixmap, sizeof (Pixmap)); - *data++ = input->left; - *data++ = input->right; - *data++ = input->top; - *data++ = input->bottom; - - *data++ = max_input->left; - *data++ = max_input->right; - *data++ = max_input->top; - *data++ = max_input->bottom; + *data++ = frame->left; + *data++ = frame->right; + *data++ = frame->top; + *data++ = frame->bottom; + *data++ = border->left; + *data++ = border->right; + *data++ = border->top; + *data++ = border->bottom; + + *data++ = max_frame->left; + *data++ = max_frame->right; + *data++ = max_frame->top; + *data++ = max_frame->bottom; + *data++ = max_border->left; + *data++ = max_border->right; + *data++ = max_border->top; + *data++ = max_border->bottom; *data++ = min_width; *data++ = min_height; @@ -190,8 +214,10 @@ int decor_pixmap_property_to_quads (long *data, int size, Pixmap *pixmap, - decor_extents_t *input, - decor_extents_t *max_input, + decor_extents_t *frame, + decor_extents_t *border, + decor_extents_t *max_frame, + decor_extents_t *max_border, int *min_width, int *min_height, decor_quad_t *quad) @@ -212,15 +238,23 @@ decor_pixmap_property_to_quads (long *data, memcpy (pixmap, data++, sizeof (Pixmap)); - input->left = *data++; - input->right = *data++; - input->top = *data++; - input->bottom = *data++; - - max_input->left = *data++; - max_input->right = *data++; - max_input->top = *data++; - max_input->bottom = *data++; + frame->left = *data++; + frame->right = *data++; + frame->top = *data++; + frame->bottom = *data++; + border->left = *data++; + border->right = *data++; + border->top = *data++; + border->bottom = *data++; + + max_frame->left = *data++; + max_frame->right = *data++; + max_frame->top = *data++; + max_frame->bottom = *data++; + max_border->left = *data++; + max_border->right = *data++; + max_border->top = *data++; + max_border->bottom = *data++; *min_width = *data++; *min_height = *data++; diff --git a/plugins/decor/src/decor.cpp b/plugins/decor/src/decor.cpp index 9c34534..4ce2228 100644 --- a/plugins/decor/src/decor.cpp +++ b/plugins/decor/src/decor.cpp @@ -286,9 +286,12 @@ Decoration::create (Window id, int result, format; unsigned long n, nleft; unsigned char *data; + unsigned char *data_orig; long *prop; Pixmap pixmap = None; + decor_extents_t border; decor_extents_t input; + decor_extents_t maxBorder; decor_extents_t maxInput; decor_quad_t *quad = NULL; int nQuad = 0; @@ -327,7 +330,6 @@ Decoration::create (Window id, if (type == WINDOW_DECORATION_TYPE_PIXMAP) { - nQuad = (n - BASE_PROP_SIZE) / QUAD_PROP_SIZE; quad = new decor_quad_t [nQuad]; @@ -338,8 +340,8 @@ Decoration::create (Window id, } nQuad = decor_pixmap_property_to_quads (prop, n, &pixmap, &input, - &maxInput, &minWidth, - &minHeight, quad); + &border, &maxInput, + &maxBorder, &minWidth, &minHeight, quad); XFree (data); @@ -357,6 +359,10 @@ Decoration::create (Window id, XFree (data); return NULL; } + + border = input; + maxBorder = maxInput; + XFree (data); } else @@ -423,16 +429,34 @@ Decoration::create (Window id, decoration->output.bottom = MAX (input.bottom, maxInput.bottom); } + /* Extents of actual frame window */ + decoration->input.left = input.left; decoration->input.right = input.right; decoration->input.top = input.top; decoration->input.bottom = input.bottom; + /* Border extents */ + + decoration->border.left = border.left; + decoration->border.right = border.right; + decoration->border.top = border.top; + decoration->border.bottom = border.bottom; + + /* Extents of actual frame window */ + decoration->maxInput.left = maxInput.left; decoration->maxInput.right = maxInput.right; decoration->maxInput.top = maxInput.top; decoration->maxInput.bottom = maxInput.bottom; + /* Border extents */ + + decoration->maxBorder.left = maxBorder.left; + decoration->maxBorder.right = maxBorder.right; + decoration->maxBorder.top = maxBorder.top; + decoration->maxBorder.bottom = maxBorder.bottom; + decoration->refCount = 1; decoration->type = type; @@ -756,9 +780,11 @@ DecorWindow::update (bool allowDecoration) return false; if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE) - window->setWindowFrameExtents (&wd->decor->maxInput); + window->setWindowFrameExtents (&wd->decor->maxBorder, + &wd->decor->maxInput); else if (!window->hasUnmapReference ()) - window->setWindowFrameExtents (&wd->decor->input); + window->setWindowFrameExtents (&wd->decor->border, + &wd->decor->input); moveDx = shiftX () - oldShiftX; moveDy = shiftY () - oldShiftY; @@ -778,7 +804,7 @@ DecorWindow::update (bool allowDecoration) memset (&emptyExtents, 0, sizeof (CompWindowExtents)); - window->setWindowFrameExtents (&emptyExtents); + window->setWindowFrameExtents (&emptyExtents, &emptyExtents); moveDx = -oldShiftX; moveDy = -oldShiftY; @@ -834,8 +860,10 @@ DecorWindow::update (bool allowDecoration) void DecorWindow::updateFrame () { - if (!wd || !(window->input ().left || window->input ().right || - window->input ().top || window->input ().bottom) || + if (!wd || !(wd->decor->input.left || wd->decor->input.left || + wd->decor->input.left || wd->decor->input.bottom) || + !(wd->decor->maxInput.left || wd->decor->maxInput.left || + wd->decor->maxInput.left || wd->decor->maxInput.bottom) || (wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP && outputFrame) || (wd->decor->type == WINDOW_DECORATION_TYPE_WINDOW && inputFrame)) { @@ -869,8 +897,10 @@ DecorWindow::updateFrame () oldHeight = 0; } } - if (wd && (window->input ().left || window->input ().right || - window->input ().top || window->input ().bottom)) + if (wd && (wd->decor->input.left || wd->decor->input.left || + wd->decor->input.left || wd->decor->input.bottom || + wd->decor->maxInput.left || wd->decor->maxInput.left || + wd->decor->maxInput.left || wd->decor->maxInput.bottom)) { if (wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP) updateInputFrame (); @@ -886,15 +916,22 @@ DecorWindow::updateInputFrame () int x, y, width, height; CompWindow::Geometry server = window->serverGeometry (); int bw = server.border () * 2; - CompWindowExtents input; + CompWindowExtents input; + CompWindowExtents border; if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE) + { + border = wd->decor->maxBorder; input = wd->decor->maxInput; + } else + { + border = wd->decor->border; input = wd->decor->input; + } - x = window->input ().left - input.left; - y = window->input ().top - input.top; + x = window->input ().left - border.left; + y = window->input ().top - border.top; width = server.width () + input.left + input.right + bw; height = server.height ()+ input.top + input.bottom + bw; @@ -998,7 +1035,7 @@ DecorWindow::updateOutputFrame () int x, y, width, height; CompWindow::Geometry server = window->serverGeometry (); int bw = server.border () * 2; - CompWindowExtents input; + CompWindowExtents input; if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE) input = wd->decor->maxInput; @@ -1222,8 +1259,8 @@ DecorWindow::updateFrameRegion (CompRegion ®ion) x = window->geometry (). x (); y = window->geometry (). y (); - region += frameRegion.translated (x - window->input ().left, - y - window->input ().top); + region += frameRegion.translated (x - wd->decor->input.left, + y - wd->decor->input.top); } else { @@ -1713,9 +1750,11 @@ DecorWindow::stateChangeNotify (unsigned int lastState) if (wd && wd->decor) { if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE) - window->setWindowFrameExtents (&wd->decor->maxInput); + window->setWindowFrameExtents (&wd->decor->maxBorder, + &wd->decor->maxInput); else - window->setWindowFrameExtents (&wd->decor->input); + window->setWindowFrameExtents (&wd->decor->border, + &wd->decor->input); updateFrame (); } @@ -1838,7 +1877,8 @@ DecorWindow::DecorWindow (CompWindow *w) : pixmapFailed (false), regions (), updateReg (true), - unshading (false) + unshading (false), + shading (false) { WindowInterface::setHandler (window); diff --git a/plugins/decor/src/decor.h b/plugins/decor/src/decor.h index f382639..c579265 100644 --- a/plugins/decor/src/decor.h +++ b/plugins/decor/src/decor.h @@ -74,8 +74,10 @@ class Decoration { int refCount; DecorTexture *texture; CompWindowExtents output; - CompWindowExtents input; - CompWindowExtents maxInput; + CompWindowExtents border; + CompWindowExtents input; + CompWindowExtents maxBorder; + CompWindowExtents maxInput; int minWidth; int minHeight; decor_quad_t *quad; diff --git a/src/privatewindow.h b/src/privatewindow.h index 4cecac2..4bed1bc 100644 --- a/src/privatewindow.h +++ b/src/privatewindow.h @@ -277,6 +277,7 @@ class PrivateWindow { bool alive; CompWindowExtents input; + CompWindowExtents border; CompWindowExtents output; CompStruts *struts; diff --git a/src/window.cpp b/src/window.cpp index 37989e4..2da9c95 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -5006,7 +5006,7 @@ CompWindow::shaded () CompWindowExtents & CompWindow::input () const { - return priv->input; + return priv->border; } CompWindowExtents & @@ -5609,19 +5609,26 @@ CompWindow::updateFrameRegion () } void -CompWindow::setWindowFrameExtents (CompWindowExtents *i) +CompWindow::setWindowFrameExtents (CompWindowExtents *b, + CompWindowExtents *i) { - if (priv->input.left != i->left || + /* Input extents are used for frame size, + * Border extents used for placement. + */ + + if (!i) + i = b; + + if (priv->input.left != i->left || priv->input.right != i->right || - priv->input.top != i->top || + priv->input.top != i->top || priv->input.bottom != i->bottom) { unsigned long data[4]; priv->input = *i; + priv->border = *b; - priv->updateFrameWindow (); - priv->updateSize (); recalcActions (); data[0] = i->left; @@ -5633,6 +5640,8 @@ CompWindow::setWindowFrameExtents (CompWindowExtents *i) Atoms::frameExtents, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) data, 4); + priv->updateSize (); + priv->updateFrameWindow (); } } |