diff options
author | David Reveman <davidr@novell.com> | 2008-03-10 03:45:55 -0400 |
---|---|---|
committer | David Reveman <davidr@novell.com> | 2008-03-10 12:18:41 -0400 |
commit | 121c627076bd05bce98bf6837ddeab6dcb6df3db (patch) | |
tree | 909ad80f7f150ddd03fb84738ef1e6ce8b7da151 | |
parent | 75683042a17d67e0d7333beeadd14d99d6bd1d71 (diff) |
Add public raise and lower functions to window object type.
-rw-r--r-- | include/compiz/core.h | 12 | ||||
-rw-r--r-- | metadata/org.compiz.window.xml.in | 8 | ||||
-rw-r--r-- | plugins/rotate.c | 2 | ||||
-rw-r--r-- | src/display.c | 46 | ||||
-rw-r--r-- | src/event.c | 8 | ||||
-rw-r--r-- | src/window.c | 676 |
6 files changed, 369 insertions, 383 deletions
diff --git a/include/compiz/core.h b/include/compiz/core.h index fd5bead0..61777be3 100644 --- a/include/compiz/core.h +++ b/include/compiz/core.h @@ -2628,6 +2628,10 @@ typedef struct _CompStruts { typedef void (*CloseWindowProc) (CompWindow *w, int32_t eventTime); +typedef void (*RaiseWindowProc) (CompWindow *w); + +typedef void (*LowerWindowProc) (CompWindow *w); + typedef void (*XButtonEventProc) (CompWindow *w, int32_t button, int32_t state, @@ -2648,6 +2652,8 @@ typedef struct _CompWindowVTable { /* public methods */ CloseWindowProc close; + RaiseWindowProc raise; + RaiseWindowProc lower; /* public signals */ XButtonEventProc xButtonPress; @@ -3079,12 +3085,6 @@ void updateWindowSize (CompWindow *w); void -raiseWindow (CompWindow *w); - -void -lowerWindow (CompWindow *w); - -void restackWindowAbove (CompWindow *w, CompWindow *sibling); diff --git a/metadata/org.compiz.window.xml.in b/metadata/org.compiz.window.xml.in index 6a369358..18c95b7b 100644 --- a/metadata/org.compiz.window.xml.in +++ b/metadata/org.compiz.window.xml.in @@ -5,6 +5,14 @@ <_long>Close window using WM_DELETE_WINDOW protocol if supported by window client</_long> <arg name="eventTime" type="i" direction="in"/> </method> + <method name="raise"> + <_short>Raise Window</_short> + <_long>Raise window</_long> + </method> + <method name="lower"> + <_short>Lower Window</_short> + <_long>Lower window</_long> + </method> <signal name="xButtonPress"> <_short>Button Press</_short> <_long>Indicates that a button press event has occurred</_long> diff --git a/plugins/rotate.c b/plugins/rotate.c index 23d85275..da772815 100644 --- a/plugins/rotate.c +++ b/plugins/rotate.c @@ -829,7 +829,7 @@ rotateWithWindow (CompDisplay *d, rs->moveWindowX = w->attrib.x; if (raise) - raiseWindow (w); + (*w->u.vTable->raise) (w); } } } diff --git a/src/display.c b/src/display.c index e8130123..e6d4fb52 100644 --- a/src/display.c +++ b/src/display.c @@ -599,44 +599,6 @@ showDesktop (CompDisplay *d, return TRUE; } -static Bool -raiseInitiate (CompDisplay *d, - CompAction *action, - CompActionState state, - CompOption *option, - int nOption) -{ - CompWindow *w; - Window xid; - - xid = getIntOptionNamed (option, nOption, "window", 0); - - w = findTopLevelWindowAtDisplay (d, xid); - if (w) - raiseWindow (w); - - return TRUE; -} - -static Bool -lowerInitiate (CompDisplay *d, - CompAction *action, - CompActionState state, - CompOption *option, - int nOption) -{ - CompWindow *w; - Window xid; - - xid = getIntOptionNamed (option, nOption, "window", 0); - - w = findTopLevelWindowAtDisplay (d, xid); - if (w) - lowerWindow (w); - - return TRUE; -} - static void changeWindowOpacity (CompWindow *w, int direction) @@ -857,10 +819,10 @@ const CompMetadataOptionInfo coreDisplayOptionInfo[COMP_DISPLAY_OPTION_NUM] = { { "run_command10_key", "key", 0, 0, 0 }, { "run_command11_key", "key", 0, 0, 0 }, { "slow_animations_key", "key", 0, 0, 0 }, - { "raise_window_key", "key", 0, raiseInitiate, 0 }, - { "raise_window_button", "button", 0, raiseInitiate, 0 }, - { "lower_window_key", "key", 0, lowerInitiate, 0 }, - { "lower_window_button", "button", 0, lowerInitiate, 0 }, + { "raise_window_key", "key", 0, 0, 0 }, + { "raise_window_button", "button", 0, 0, 0 }, + { "lower_window_key", "key", 0, 0, 0 }, + { "lower_window_button", "button", 0, 0, 0 }, { "unmaximize_window_key", "key", 0, unmaximize, 0 }, { "minimize_window_key", "key", 0, minimize, 0 }, { "minimize_window_button", "button", 0, minimize, 0 }, diff --git a/src/event.c b/src/event.c index 5b2c420e..f4681ffa 100644 --- a/src/event.c +++ b/src/event.c @@ -1884,9 +1884,9 @@ handleEvent (CompDisplay *d, else { if (event->xclient.data.l[2] == Above) - raiseWindow (w); + (*w->u.vTable->raise) (w); else if (event->xclient.data.l[2] == Below) - lowerWindow (w); + (*w->u.vTable->lower) (w); } } } @@ -2069,7 +2069,7 @@ handleEvent (CompDisplay *d, restackWindowAbove (w, sibling); } else - raiseWindow (w); + (*w->u.vTable->raise) (w); } break; case Below: @@ -2079,7 +2079,7 @@ handleEvent (CompDisplay *d, restackWindowBelow (w, sibling); } else - lowerWindow (w); + (*w->u.vTable->lower) (w); break; default: /* no handling of the TopIf, BottomIf, Opposite cases - diff --git a/src/window.c b/src/window.c index d85f9068..9de0c0cb 100644 --- a/src/window.c +++ b/src/window.c @@ -1782,6 +1782,348 @@ noopClose (CompWindow *w, FOR_BASE (&w->u.base.u.base, (*w->u.vTable->close) (w, eventTime)); } +static int +addWindowStackChanges (CompWindow *w, + XWindowChanges *xwc, + CompWindow *sibling) +{ + int mask = 0; + + if (!sibling || sibling->id != w->id) + { + if (w->prev) + { + if (!sibling) + { + XLowerWindow (w->screen->display->display, w->id); + if (w->frame) + XLowerWindow (w->screen->display->display, w->frame); + } + else if (sibling->id != w->prev->id) + { + mask |= CWSibling | CWStackMode; + + xwc->stack_mode = Above; + xwc->sibling = sibling->id; + } + } + else if (sibling) + { + mask |= CWSibling | CWStackMode; + + xwc->stack_mode = Above; + xwc->sibling = sibling->id; + } + } + + if (sibling && mask) + { + /* a normal window can be stacked above fullscreen windows but we + don't want normal windows to be stacked above dock window so if + the sibling we're stacking above is a fullscreen window we also + update all dock windows. */ + if ((sibling->type & CompWindowTypeFullscreenMask) && + (!(w->type & (CompWindowTypeFullscreenMask | + CompWindowTypeDockMask))) && + !isAncestorTo (w, sibling)) + { + CompWindow *dw; + + for (dw = w->screen->reverseWindows; dw; dw = dw->prev) + if (dw == sibling) + break; + + for (; dw; dw = dw->prev) + if (dw->type & CompWindowTypeDockMask) + configureXWindow (dw, mask, xwc); + } + } + + return mask; +} + +static Bool +isGroupTransient (CompWindow *w, + Window clientLeader) +{ + if (!clientLeader) + return FALSE; + + if (w->transientFor == None || w->transientFor == w->screen->root) + { + if (w->type & (CompWindowTypeDialogMask | + CompWindowTypeModalDialogMask)) + { + if (w->clientLeader == clientLeader) + return TRUE; + } + } + + return FALSE; +} + +static Bool +avoidStackingRelativeTo (CompWindow *w) +{ + if (w->attrib.override_redirect) + return TRUE; + + if (!w->shaded && !w->pendingMaps) + { + if (w->attrib.map_state != IsViewable || w->mapNum == 0) + return TRUE; + } + + return FALSE; +} + +static Bool +stackLayerCheck (CompWindow *w, + Window clientLeader, + CompWindow *below) +{ + if (isAncestorTo (w, below)) + return TRUE; + + if (isAncestorTo (below, w)) + return FALSE; + + if (clientLeader && below->clientLeader == clientLeader) + if (isGroupTransient (below, clientLeader)) + return FALSE; + + if (w->state & CompWindowStateAboveMask) + { + return TRUE; + } + else if (w->state & CompWindowStateBelowMask) + { + if (below->state & CompWindowStateBelowMask) + return TRUE; + } + else if (!(below->state & CompWindowStateAboveMask)) + { + return TRUE; + } + + return FALSE; +} + +/* goes through the stack, top-down until we find a window we should + stack above, normal windows can be stacked above fullscreen windows + if aboveFs is TRUE. */ +static CompWindow * +findSiblingBelow (CompWindow *w, + Bool aboveFs) +{ + CompWindow *below; + Window clientLeader = w->clientLeader; + unsigned int type = w->type; + unsigned int belowMask; + + if (aboveFs) + belowMask = CompWindowTypeDockMask; + else + belowMask = CompWindowTypeDockMask | CompWindowTypeFullscreenMask; + + /* normal stacking of fullscreen windows with below state */ + if ((type & CompWindowTypeFullscreenMask) && + (w->state & CompWindowStateBelowMask)) + type = CompWindowTypeNormalMask; + + if (w->transientFor || isGroupTransient (w, clientLeader)) + clientLeader = None; + + for (below = w->screen->reverseWindows; below; below = below->prev) + { + if (below == w || avoidStackingRelativeTo (below)) + continue; + + /* always above desktop windows */ + if (below->type & CompWindowTypeDesktopMask) + return below; + + switch (type) { + case CompWindowTypeDesktopMask: + /* desktop window layer */ + break; + case CompWindowTypeFullscreenMask: + case CompWindowTypeDockMask: + /* fullscreen and dock layer */ + if (below->type & (CompWindowTypeFullscreenMask | + CompWindowTypeDockMask)) + { + if (stackLayerCheck (w, clientLeader, below)) + return below; + } + else + { + return below; + } + break; + default: + /* fullscreen and normal layer */ + if (!(below->type & belowMask)) + { + if (stackLayerCheck (w, clientLeader, below)) + return below; + } + break; + } + } + + return NULL; +} + +/* goes through the stack, top-down and returns the lowest window we + can stack above. */ +static CompWindow * +findLowestSiblingBelow (CompWindow *w) +{ + CompWindow *below, *lowest = w->screen->reverseWindows; + Window clientLeader = w->clientLeader; + unsigned int type = w->type; + + /* normal stacking fullscreen windows with below state */ + if ((type & CompWindowTypeFullscreenMask) && + (w->state & CompWindowStateBelowMask)) + type = CompWindowTypeNormalMask; + + if (w->transientFor || isGroupTransient (w, clientLeader)) + clientLeader = None; + + for (below = w->screen->reverseWindows; below; below = below->prev) + { + if (below == w || avoidStackingRelativeTo (below)) + continue; + + /* always above desktop windows */ + if (below->type & CompWindowTypeDesktopMask) + return below; + + switch (type) { + case CompWindowTypeDesktopMask: + /* desktop window layer - desktop windows always should be + stacked at the bottom; no other window should be below them */ + return NULL; + break; + case CompWindowTypeFullscreenMask: + case CompWindowTypeDockMask: + /* fullscreen and dock layer */ + if (below->type & (CompWindowTypeFullscreenMask | + CompWindowTypeDockMask)) + { + if (!stackLayerCheck (below, clientLeader, w)) + return lowest; + } + else + { + return lowest; + } + break; + default: + /* fullscreen and normal layer */ + if (!(below->type & CompWindowTypeDockMask)) + { + if (!stackLayerCheck (below, clientLeader, w)) + return lowest; + } + break; + } + + lowest = below; + } + + return lowest; +} + +static Bool +validSiblingBelow (CompWindow *w, + CompWindow *sibling) +{ + Window clientLeader = w->clientLeader; + unsigned int type = w->type; + + /* normal stacking fullscreen windows with below state */ + if ((type & CompWindowTypeFullscreenMask) && + (w->state & CompWindowStateBelowMask)) + type = CompWindowTypeNormalMask; + + if (w->transientFor || isGroupTransient (w, clientLeader)) + clientLeader = None; + + if (sibling == w || avoidStackingRelativeTo (sibling)) + return FALSE; + + /* always above desktop windows */ + if (sibling->type & CompWindowTypeDesktopMask) + return TRUE; + + switch (type) { + case CompWindowTypeDesktopMask: + /* desktop window layer */ + break; + case CompWindowTypeFullscreenMask: + case CompWindowTypeDockMask: + /* fullscreen and dock layer */ + if (sibling->type & (CompWindowTypeFullscreenMask | + CompWindowTypeDockMask)) + { + if (stackLayerCheck (w, clientLeader, sibling)) + return TRUE; + } + else + { + return TRUE; + } + break; + default: + /* fullscreen and normal layer */ + if (!(sibling->type & CompWindowTypeDockMask)) + { + if (stackLayerCheck (w, clientLeader, sibling)) + return TRUE; + } + break; + } + + return FALSE; +} + +static void +raiseWindow (CompWindow *w) +{ + XWindowChanges xwc; + int mask; + + mask = addWindowStackChanges (w, &xwc, findSiblingBelow (w, FALSE)); + if (mask) + configureXWindow (w, mask, &xwc); +} + +static void +noopRaiseWindow (CompWindow *w) +{ + FOR_BASE (&w->u.base.u.base, (*w->u.vTable->raise) (w)); +} + +static void +lowerWindow (CompWindow *w) +{ + XWindowChanges xwc; + int mask; + + mask = addWindowStackChanges (w, &xwc, findLowestSiblingBelow (w)); + if (mask) + configureXWindow (w, mask, &xwc); +} + +static void +noopLowerWindow (CompWindow *w) +{ + FOR_BASE (&w->u.base.u.base, (*w->u.vTable->lower) (w)); +} + static int32_t windowVirtualModifiers (CompWindow *w, int state) @@ -1966,6 +2308,8 @@ static const CompWindowVTable windowObjectVTable = { /* public methods */ .close = close, + .raise = raiseWindow, + .lower = lowerWindow, /* public signals */ .xButtonPress = xButtonPress, @@ -1977,6 +2321,8 @@ static const CompWindowVTable windowObjectVTable = { static const CompWindowVTable noopWindowObjectVTable = { .close = noopClose, + .raise = noopRaiseWindow, + .lower = noopLowerWindow, .xButtonPress = noopXButtonPress, .xButtonRelease = noopXButtonRelease, .xKeyPress = noopXKeyPress, @@ -3119,26 +3465,6 @@ windowStateChangeNotify (CompWindow *w, { } -static Bool -isGroupTransient (CompWindow *w, - Window clientLeader) -{ - if (!clientLeader) - return FALSE; - - if (w->transientFor == None || w->transientFor == w->screen->root) - { - if (w->type & (CompWindowTypeDialogMask | - CompWindowTypeModalDialogMask)) - { - if (w->clientLeader == clientLeader) - return TRUE; - } - } - - return FALSE; -} - static CompWindow * getModalTransient (CompWindow *window) { @@ -3263,234 +3589,6 @@ moveInputFocusToWindow (CompWindow *w) } } -static Bool -stackLayerCheck (CompWindow *w, - Window clientLeader, - CompWindow *below) -{ - if (isAncestorTo (w, below)) - return TRUE; - - if (isAncestorTo (below, w)) - return FALSE; - - if (clientLeader && below->clientLeader == clientLeader) - if (isGroupTransient (below, clientLeader)) - return FALSE; - - if (w->state & CompWindowStateAboveMask) - { - return TRUE; - } - else if (w->state & CompWindowStateBelowMask) - { - if (below->state & CompWindowStateBelowMask) - return TRUE; - } - else if (!(below->state & CompWindowStateAboveMask)) - { - return TRUE; - } - - return FALSE; -} - -static Bool -avoidStackingRelativeTo (CompWindow *w) -{ - if (w->attrib.override_redirect) - return TRUE; - - if (!w->shaded && !w->pendingMaps) - { - if (w->attrib.map_state != IsViewable || w->mapNum == 0) - return TRUE; - } - - return FALSE; -} - -/* goes through the stack, top-down until we find a window we should - stack above, normal windows can be stacked above fullscreen windows - if aboveFs is TRUE. */ -static CompWindow * -findSiblingBelow (CompWindow *w, - Bool aboveFs) -{ - CompWindow *below; - Window clientLeader = w->clientLeader; - unsigned int type = w->type; - unsigned int belowMask; - - if (aboveFs) - belowMask = CompWindowTypeDockMask; - else - belowMask = CompWindowTypeDockMask | CompWindowTypeFullscreenMask; - - /* normal stacking of fullscreen windows with below state */ - if ((type & CompWindowTypeFullscreenMask) && - (w->state & CompWindowStateBelowMask)) - type = CompWindowTypeNormalMask; - - if (w->transientFor || isGroupTransient (w, clientLeader)) - clientLeader = None; - - for (below = w->screen->reverseWindows; below; below = below->prev) - { - if (below == w || avoidStackingRelativeTo (below)) - continue; - - /* always above desktop windows */ - if (below->type & CompWindowTypeDesktopMask) - return below; - - switch (type) { - case CompWindowTypeDesktopMask: - /* desktop window layer */ - break; - case CompWindowTypeFullscreenMask: - case CompWindowTypeDockMask: - /* fullscreen and dock layer */ - if (below->type & (CompWindowTypeFullscreenMask | - CompWindowTypeDockMask)) - { - if (stackLayerCheck (w, clientLeader, below)) - return below; - } - else - { - return below; - } - break; - default: - /* fullscreen and normal layer */ - if (!(below->type & belowMask)) - { - if (stackLayerCheck (w, clientLeader, below)) - return below; - } - break; - } - } - - return NULL; -} - -/* goes through the stack, top-down and returns the lowest window we - can stack above. */ -static CompWindow * -findLowestSiblingBelow (CompWindow *w) -{ - CompWindow *below, *lowest = w->screen->reverseWindows; - Window clientLeader = w->clientLeader; - unsigned int type = w->type; - - /* normal stacking fullscreen windows with below state */ - if ((type & CompWindowTypeFullscreenMask) && - (w->state & CompWindowStateBelowMask)) - type = CompWindowTypeNormalMask; - - if (w->transientFor || isGroupTransient (w, clientLeader)) - clientLeader = None; - - for (below = w->screen->reverseWindows; below; below = below->prev) - { - if (below == w || avoidStackingRelativeTo (below)) - continue; - - /* always above desktop windows */ - if (below->type & CompWindowTypeDesktopMask) - return below; - - switch (type) { - case CompWindowTypeDesktopMask: - /* desktop window layer - desktop windows always should be - stacked at the bottom; no other window should be below them */ - return NULL; - break; - case CompWindowTypeFullscreenMask: - case CompWindowTypeDockMask: - /* fullscreen and dock layer */ - if (below->type & (CompWindowTypeFullscreenMask | - CompWindowTypeDockMask)) - { - if (!stackLayerCheck (below, clientLeader, w)) - return lowest; - } - else - { - return lowest; - } - break; - default: - /* fullscreen and normal layer */ - if (!(below->type & CompWindowTypeDockMask)) - { - if (!stackLayerCheck (below, clientLeader, w)) - return lowest; - } - break; - } - - lowest = below; - } - - return lowest; -} - -static Bool -validSiblingBelow (CompWindow *w, - CompWindow *sibling) -{ - Window clientLeader = w->clientLeader; - unsigned int type = w->type; - - /* normal stacking fullscreen windows with below state */ - if ((type & CompWindowTypeFullscreenMask) && - (w->state & CompWindowStateBelowMask)) - type = CompWindowTypeNormalMask; - - if (w->transientFor || isGroupTransient (w, clientLeader)) - clientLeader = None; - - if (sibling == w || avoidStackingRelativeTo (sibling)) - return FALSE; - - /* always above desktop windows */ - if (sibling->type & CompWindowTypeDesktopMask) - return TRUE; - - switch (type) { - case CompWindowTypeDesktopMask: - /* desktop window layer */ - break; - case CompWindowTypeFullscreenMask: - case CompWindowTypeDockMask: - /* fullscreen and dock layer */ - if (sibling->type & (CompWindowTypeFullscreenMask | - CompWindowTypeDockMask)) - { - if (stackLayerCheck (w, clientLeader, sibling)) - return TRUE; - } - else - { - return TRUE; - } - break; - default: - /* fullscreen and normal layer */ - if (!(sibling->type & CompWindowTypeDockMask)) - { - if (stackLayerCheck (w, clientLeader, sibling)) - return TRUE; - } - break; - } - - return FALSE; -} - static void saveWindowGeometry (CompWindow *w, int mask) @@ -4136,88 +4234,6 @@ updateWindowSize (CompWindow *w) } } -static int -addWindowStackChanges (CompWindow *w, - XWindowChanges *xwc, - CompWindow *sibling) -{ - int mask = 0; - - if (!sibling || sibling->id != w->id) - { - if (w->prev) - { - if (!sibling) - { - XLowerWindow (w->screen->display->display, w->id); - if (w->frame) - XLowerWindow (w->screen->display->display, w->frame); - } - else if (sibling->id != w->prev->id) - { - mask |= CWSibling | CWStackMode; - - xwc->stack_mode = Above; - xwc->sibling = sibling->id; - } - } - else if (sibling) - { - mask |= CWSibling | CWStackMode; - - xwc->stack_mode = Above; - xwc->sibling = sibling->id; - } - } - - if (sibling && mask) - { - /* a normal window can be stacked above fullscreen windows but we - don't want normal windows to be stacked above dock window so if - the sibling we're stacking above is a fullscreen window we also - update all dock windows. */ - if ((sibling->type & CompWindowTypeFullscreenMask) && - (!(w->type & (CompWindowTypeFullscreenMask | - CompWindowTypeDockMask))) && - !isAncestorTo (w, sibling)) - { - CompWindow *dw; - - for (dw = w->screen->reverseWindows; dw; dw = dw->prev) - if (dw == sibling) - break; - - for (; dw; dw = dw->prev) - if (dw->type & CompWindowTypeDockMask) - configureXWindow (dw, mask, xwc); - } - } - - return mask; -} - -void -raiseWindow (CompWindow *w) -{ - XWindowChanges xwc; - int mask; - - mask = addWindowStackChanges (w, &xwc, findSiblingBelow (w, FALSE)); - if (mask) - configureXWindow (w, mask, &xwc); -} - -void -lowerWindow (CompWindow *w) -{ - XWindowChanges xwc; - int mask; - - mask = addWindowStackChanges (w, &xwc, findLowestSiblingBelow (w)); - if (mask) - configureXWindow (w, mask, &xwc); -} - void restackWindowAbove (CompWindow *w, CompWindow *sibling) |