diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | gtk/window-decorator/gtk-window-decorator.c | 2 | ||||
-rw-r--r-- | include/decoration.h | 5 | ||||
-rw-r--r-- | kde/window-decorator-kde4/utils.cpp | 2 | ||||
-rw-r--r-- | kde/window-decorator/utils.cpp | 2 | ||||
-rw-r--r-- | libdecoration/decoration.c | 49 | ||||
-rw-r--r-- | plugins/decor.cpp | 134 | ||||
-rw-r--r-- | plugins/decor.h | 12 |
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; }; |