summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <sam.spilsbury@canonical.com>2011-02-01 17:26:11 +0800
committerSam Spilsbury <sam.spilsbury@canonical.com>2011-02-01 17:26:11 +0800
commit4ae95852e53075caed1558620127f0c1405fe474 (patch)
tree12396907cfded0311fa4afc7064d3afc9b7a9241
parenteda4ce59d1010289f1cdd62e4ce03a3517dd61da (diff)
downloadcompiz-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.txt2
-rw-r--r--gtk/window-decorator/decorator.c3
-rw-r--r--gtk/window-decorator/decorprops.c3
-rw-r--r--gtk/window-decorator/metacity.c3
-rw-r--r--include/core/core.h2
-rw-r--r--include/core/window.h3
-rw-r--r--include/decoration.h10
-rw-r--r--kde/window-decorator-kde4/decorator.cpp2
-rw-r--r--kde/window-decorator-kde4/switcher.cpp4
-rw-r--r--kde/window-decorator-kde4/window.cpp3
-rw-r--r--libdecoration/decoration.c120
-rw-r--r--plugins/decor/src/decor.cpp78
-rw-r--r--plugins/decor/src/decor.h6
-rw-r--r--src/privatewindow.h1
-rw-r--r--src/window.cpp21
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 &region)
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 ();
}
}