summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kasprzyk <onestone@compiz-fusion.org>2008-09-01 18:00:34 +0200
committerDennis kasprzyk <onestone@compiz-fusion.org>2008-09-01 18:00:34 +0200
commitef26ae19916a44e17361439f7b2b8a1d04fc8d7d (patch)
tree00a06f6a1e3e5aacaedb9388461f2ddc8fa243bf
parent1f6d68d83d9188198ee5c94248b8a80fe42bc3ef (diff)
downloadcompiz-with-glib-mainloop-ef26ae19916a44e17361439f7b2b8a1d04fc8d7d.tar.gz
compiz-with-glib-mainloop-ef26ae19916a44e17361439f7b2b8a1d04fc8d7d.tar.bz2
- Added a type field to the decoration property.
- Use a separate frame window for decorations.
-rw-r--r--configure.ac2
-rw-r--r--gtk/window-decorator/gtk-window-decorator.c2
-rw-r--r--include/decoration.h5
-rw-r--r--kde/window-decorator-kde4/utils.cpp2
-rw-r--r--kde/window-decorator/utils.cpp2
-rw-r--r--libdecoration/decoration.c49
-rw-r--r--plugins/decor.cpp134
-rw-r--r--plugins/decor.h12
8 files changed, 179 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac
index 79a9992..0fbcc6f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ AC_PROG_INTLTOOL([0.23])
AM_MAINTAINER_MODE
dnl decorator interface version
-AC_DEFINE(DECOR_INTERFACE_VERSION, 20080529, [Decorator interface version])
+AC_DEFINE(DECOR_INTERFACE_VERSION, 20080901, [Decorator interface version])
AC_ISC_POSIX
AC_PROG_CC
diff --git a/gtk/window-decorator/gtk-window-decorator.c b/gtk/window-decorator/gtk-window-decorator.c
index 4802c93..7cd7532 100644
--- a/gtk/window-decorator/gtk-window-decorator.c
+++ b/gtk/window-decorator/gtk-window-decorator.c
@@ -6998,7 +6998,7 @@ main (int argc, char *argv[])
xdisplay = gdk_x11_display_get_xdisplay (gdkdisplay);
gdkscreen = gdk_display_get_default_screen (gdkdisplay);
- frame_window_atom = XInternAtom (xdisplay, "_NET_FRAME_WINDOW", FALSE);
+ frame_window_atom = XInternAtom (xdisplay, DECOR_INPUT_FRAME_ATOM_NAME, FALSE);
win_decor_atom = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, FALSE);
win_blur_decor_atom = XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, FALSE);
wm_move_resize_atom = XInternAtom (xdisplay, "_NET_WM_MOVERESIZE", FALSE);
diff --git a/include/decoration.h b/include/decoration.h
index 5eed043..6b92121 100644
--- a/include/decoration.h
+++ b/include/decoration.h
@@ -44,6 +44,9 @@ extern "C" {
#define DECOR_BLUR_ATOM_NAME "_COMPIZ_WM_WINDOW_BLUR_DECOR"
#define DECOR_SWITCH_WINDOW_ATOM_NAME "_COMPIZ_SWITCH_SELECT_WINDOW"
#define DECOR_SWITCH_FOREGROUND_COLOR_ATOM_NAME "_COMPIZ_SWITCH_FOREGROUND_COLOR"
+#define DECOR_INPUT_FRAME_ATOM_NAME "_COMPIZ_WINDOW_DECOR_INPUT_FRAME"
+
+#define WINDOW_DECORATION_TYPE_PIXMAP 0
#define GRAVITY_WEST (1 << 0)
#define GRAVITY_EAST (1 << 1)
@@ -165,7 +168,7 @@ typedef void (*decor_draw_func_t) (Display *xdisplay,
decor_context_t *context,
void *closure);
-#define BASE_PROP_SIZE 12
+#define BASE_PROP_SIZE 13
#define QUAD_PROP_SIZE 9
#define N_QUADS_MAX 24
diff --git a/kde/window-decorator-kde4/utils.cpp b/kde/window-decorator-kde4/utils.cpp
index f6bdac6..f54ab07 100644
--- a/kde/window-decorator-kde4/utils.cpp
+++ b/kde/window-decorator-kde4/utils.cpp
@@ -180,7 +180,7 @@ KWD::Atoms::init (void)
{
Display *xdisplay = QX11Info::display();
- netFrameWindow = XInternAtom (xdisplay, "_NET_FRAME_WINDOW", false);
+ netFrameWindow = XInternAtom (xdisplay, DECOR_INPUT_FRAME_ATOM_NAME, false);
netWindowDecor = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, false);
netWindowDecorNormal =
XInternAtom (xdisplay, DECOR_NORMAL_ATOM_NAME, false);
diff --git a/kde/window-decorator/utils.cpp b/kde/window-decorator/utils.cpp
index 75dbbc6..a15c267 100644
--- a/kde/window-decorator/utils.cpp
+++ b/kde/window-decorator/utils.cpp
@@ -180,7 +180,7 @@ KWD::Atoms::init (void)
{
Display *xdisplay = qt_xdisplay ();
- netFrameWindow = XInternAtom (xdisplay, "_NET_FRAME_WINDOW", false);
+ netFrameWindow = XInternAtom (xdisplay, DECOR_INPUT_FRAME_ATOM_NAME, false);
netWindowDecor = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, false);
netWindowDecorNormal =
XInternAtom (xdisplay, DECOR_NORMAL_ATOM_NAME, false);
diff --git a/libdecoration/decoration.c b/libdecoration/decoration.c
index 1f3407c..f27a674 100644
--- a/libdecoration/decoration.c
+++ b/libdecoration/decoration.c
@@ -44,20 +44,25 @@ decor_version (void)
data[0] = version
- data[1] = pixmap
+ data[1] = decoration type
- data[2] = input left
- data[3] = input right
- data[4] = input top
- data[5] = input bottom
+ WINDOW_DECORATION_TYPE_PIXMAP property
+ --------------------------------------
- data[6] = input left when maximized
- data[7] = input right when maximized
- data[8] = input top when maximized
- data[9] = input bottom when maximized
+ data[2] = pixmap
- data[10] = min width
- data[11] = min height
+ 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
flags
@@ -65,15 +70,15 @@ 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[11 + n * 9 + 1] = flags
- data[11 + n * 9 + 2] = p1 x
- data[11 + n * 9 + 3] = p1 y
- data[11 + n * 9 + 4] = p2 x
- data[11 + n * 9 + 5] = p2 y
- data[11 + n * 9 + 6] = widthMax
- data[11 + n * 9 + 7] = heightMax
- data[11 + n * 9 + 8] = x0
- data[11 + n * 9 + 9] = y0
+ 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
*/
void
decor_quads_to_property (long *data,
@@ -86,6 +91,7 @@ decor_quads_to_property (long *data,
int nQuad)
{
*data++ = DECOR_INTERFACE_VERSION;
+ *data++ = WINDOW_DECORATION_TYPE_PIXMAP;
memcpy (data++, &pixmap, sizeof (Pixmap));
@@ -154,6 +160,9 @@ decor_property_to_quads (long *data,
data++;
+ if (*data++ != WINDOW_DECORATION_TYPE_PIXMAP)
+ return 0;
+
memcpy (pixmap, data++, sizeof (Pixmap));
input->left = *data++;
diff --git a/plugins/decor.cpp b/plugins/decor.cpp
index 4bb426e..f1c8294 100644
--- a/plugins/decor.cpp
+++ b/plugins/decor.cpp
@@ -653,6 +653,7 @@ DecorWindow::update (bool allowDecoration)
moveDx = shiftX () - oldShiftX;
moveDy = shiftY () - oldShiftY;
+ updateFrame ();
window->updateWindowOutputExtents ();
cWindow->damageOutputExtents ();
updateDecorationScale ();
@@ -668,6 +669,8 @@ DecorWindow::update (bool allowDecoration)
moveDx = -oldShiftX;
moveDy = -oldShiftY;
+
+ updateFrame ();
}
if (window->placed () && !window->attrib ().override_redirect &&
@@ -702,6 +705,107 @@ DecorWindow::update (bool allowDecoration)
}
void
+DecorWindow::updateFrame ()
+{
+ if (wd && (window->input ().left || window->input ().right ||
+ window->input ().top || window->input ().bottom))
+ {
+ XRectangle rects[4];
+ int x, y, width, height;
+ int i = 0;
+ CompWindow::Geometry server = window->serverGeometry ();
+ int bw = server.border () * 2;
+ CompWindowExtents input;
+
+ if ((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE)
+ input = wd->decor->maxInput;
+ else
+ input = wd->decor->input;
+
+ x = window->input ().left - input.left;
+ y = window->input ().top - input.top;
+ width = server.width () + input.left + input.right + bw;
+ height = server.height ()+ input.top + input.bottom + bw;
+
+ if (window->shaded ())
+ height = input.top + input.bottom;
+
+ if (!inputFrame)
+ {
+ XSetWindowAttributes attr;
+
+ attr.event_mask = StructureNotifyMask;
+ attr.override_redirect = TRUE;
+
+ inputFrame = XCreateWindow (display->dpy (), window->frame (),
+ x, y, width, height, 0, CopyFromParent,
+ InputOnly, CopyFromParent,
+ CWOverrideRedirect | CWEventMask,
+ &attr);
+
+ XGrabButton (display->dpy (), AnyButton, AnyModifier, inputFrame,
+ TRUE, ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask, GrabModeSync, GrabModeSync, None,
+ None);
+
+ XMapWindow (display->dpy (), inputFrame);
+
+ XChangeProperty (display->dpy (), window->id (),
+ dDisplay->inputFrameAtom, XA_WINDOW, 32,
+ PropModeReplace, (unsigned char *) &inputFrame, 1);
+ }
+
+ XMoveResizeWindow (display->dpy (), inputFrame, x, y, width, height);
+ XLowerWindow (display->dpy (), inputFrame);
+
+ rects[i].x = 0;
+ rects[i].y = 0;
+ rects[i].width = width;
+ rects[i].height = input.top;
+
+ if (rects[i].width && rects[i].height)
+ i++;
+
+ rects[i].x = 0;
+ rects[i].y = input.top;
+ rects[i].width = input.left;
+ rects[i].height = height - input.top - input.bottom;
+
+ if (rects[i].width && rects[i].height)
+ i++;
+
+ rects[i].x = width - input.right;
+ rects[i].y = input.top;
+ rects[i].width = input.right;
+ rects[i].height = height - input.top - input.bottom;
+
+ if (rects[i].width && rects[i].height)
+ i++;
+
+ rects[i].x = 0;
+ rects[i].y = height - input.bottom;
+ rects[i].width = width;
+ rects[i].height = input.bottom;
+
+ if (rects[i].width && rects[i].height)
+ i++;
+
+ XShapeCombineRectangles (display->dpy (), inputFrame, ShapeInput,
+ 0, 0, rects, i, ShapeSet, YXBanded);
+ }
+ else
+ {
+ if (inputFrame)
+ {
+ XDeleteProperty (display->dpy (), window->id (),
+ dDisplay->inputFrameAtom);
+ XDestroyWindow (display->dpy (), inputFrame);
+ inputFrame = None;
+ }
+ }
+}
+
+void
DecorScreen::checkForDm (bool updateWindows)
{
CompDisplay *d = screen->display ();
@@ -895,6 +999,29 @@ DecorDisplay::handleEvent (XEvent *event)
}
}
break;
+ case ConfigureNotify:
+ w = display->findTopLevelWindow (event->xproperty.window);
+ if (w)
+ {
+ DECOR_WINDOW (w);
+ if (dw->decor)
+ dw->updateFrame ();
+ }
+ break;
+ case DestroyNotify:
+ w = display->findTopLevelWindow (event->xproperty.window);
+ if (w)
+ {
+ DECOR_WINDOW (w);
+ if (dw->inputFrame &&
+ dw->inputFrame == event->xdestroywindow.window)
+ {
+ XDeleteProperty (display->dpy (), w->id (),
+ inputFrameAtom);
+ dw->inputFrame = None;
+ }
+ }
+ break;
default:
if (display->XShape () && event->type ==
display->shapeEvent () + ShapeNotify)
@@ -1039,6 +1166,7 @@ DecorWindow::stateChangeNotify (unsigned int lastState)
window->setWindowFrameExtents (&wd->decor->maxInput);
else
window->setWindowFrameExtents (&wd->decor->input);
+ updateFrame ();
}
}
@@ -1121,6 +1249,8 @@ DecorDisplay::DecorDisplay (CompDisplay *d) :
XInternAtom (d->dpy (), DECOR_NORMAL_ATOM_NAME, 0);
decorAtom[DECOR_ACTIVE] =
XInternAtom (d->dpy (), DECOR_ACTIVE_ATOM_NAME, 0);
+ inputFrameAtom =
+ XInternAtom (d->dpy (), DECOR_INPUT_FRAME_ATOM_NAME, 0);
DisplayInterface::setHandler (d);
}
@@ -1160,9 +1290,11 @@ DecorWindow::DecorWindow (CompWindow *w) :
gWindow (GLWindow::get (w)),
cWindow (CompositeWindow::get (w)),
dScreen (DecorScreen::get (w->screen ())),
+ display (w->screen ()->display ()),
dDisplay (DecorDisplay::get (w->screen ()->display ())),
wd (NULL),
- decor (NULL)
+ decor (NULL),
+ inputFrame (None)
{
if (!w->attrib ().override_redirect)
diff --git a/plugins/decor.h b/plugins/decor.h
index a1de02c..d313443 100644
--- a/plugins/decor.h
+++ b/plugins/decor.h
@@ -143,9 +143,10 @@ class DecorDisplay :
std::list<DecorTexture *> textures;
- Atom supportingDmCheckAtom;
- Atom winDecorAtom;
- Atom decorAtom[DECOR_NUM];
+ Atom supportingDmCheckAtom;
+ Atom winDecorAtom;
+ Atom decorAtom[DECOR_NUM];
+ Atom inputFrameAtom;
CompOption::Vector opt;
};
@@ -194,6 +195,8 @@ class DecorWindow :
void updateDecorationScale ();
+ void updateFrame ();
+
bool checkSize (Decoration *decor);
int shiftX ();
@@ -209,11 +212,14 @@ class DecorWindow :
GLWindow *gWindow;
CompositeWindow *cWindow;
DecorScreen *dScreen;
+ CompDisplay *display;
DecorDisplay *dDisplay;
WindowDecoration *wd;
Decoration *decor;
+ Window inputFrame;
+
CompCore::Timer resizeUpdate;
};