summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Baumann <dannybaumann@web.de>2008-10-08 21:39:45 +0200
committerDanny Baumann <dannybaumann@web.de>2008-10-08 21:39:45 +0200
commitbbe489cd524f24dc2003f0946aab49c08f6d4075 (patch)
tree776353f49a83db8e15934ec09dd868b66e7eb377
parent501d8549b316a013fb4b81a9be6bae96d8763127 (diff)
downloadwinrules-bbe489cd524f24dc2003f0946aab49c08f6d4075.tar.gz
winrules-bbe489cd524f24dc2003f0946aab49c08f6d4075.tar.bz2
Instead of modifying the cached values of input hint and protocols, hook into focusWindow to prevent focus.
Implications: - The window won't be shown in switcher. (should be ok) - Scale still focusses the window
-rw-r--r--winrules.c131
1 files changed, 72 insertions, 59 deletions
diff --git a/winrules.c b/winrules.c
index ac0b9f0..945fa85 100644
--- a/winrules.c
+++ b/winrules.c
@@ -49,10 +49,9 @@ static int displayPrivateIndex;
typedef struct _WinrulesWindow {
unsigned int allowedActions;
unsigned int stateSetMask;
- unsigned int protocolSetMask;
- Bool oldInputHint;
Bool hasAlpha;
+ Bool noFocus;
} WinrulesWindow;
typedef struct _WinrulesDisplay {
@@ -65,7 +64,10 @@ typedef struct _WinrulesDisplay {
typedef struct _WinrulesScreen {
int windowPrivateIndex;
+
GetAllowedActionsForWindowProc getAllowedActionsForWindow;
+ FocusWindowProc focusWindow;
+
CompOption opt[WINRULES_SCREEN_OPTION_NUM];
} WinrulesScreen;
@@ -92,26 +94,6 @@ typedef struct _WinrulesScreen {
#define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
-static void
-winrulesSetProtocols (CompDisplay *display,
- unsigned int protocols,
- Window id)
-{
- Atom protocol[4];
- int count = 0;
-
- if (protocols & CompWindowProtocolDeleteMask)
- protocol[count++] = display->wmDeleteWindowAtom;
- if (protocols & CompWindowProtocolTakeFocusMask)
- protocol[count++] = display->wmTakeFocusAtom;
- if (protocols & CompWindowProtocolPingMask)
- protocol[count++] = display->wmPingAtom;
- if (protocols & CompWindowProtocolSyncRequestMask)
- protocol[count++] = display->wmSyncRequestAtom;
-
- XSetWMProtocols (display->display, id, protocol, count);
-}
-
static Bool
isWinrulesWindow (CompWindow *w)
{
@@ -127,40 +109,29 @@ isWinrulesWindow (CompWindow *w)
/* FIXME? Directly set inputHint, not a problem for now
--> better should wrap into focusWindow(), only problem is focus
on MapRequest */
-static void
-winrulesSetNoFocus (CompWindow *w,
- int optNum)
+static Bool
+winrulesCheckNoFocus (CompWindow *w)
{
- unsigned int newProtocol = w->protocols;
+ Bool noFocus;
- WINRULES_SCREEN (w->screen);
WINRULES_WINDOW (w);
if (!isWinrulesWindow (w))
- return;
-
- if (matchEval (&ws->opt[optNum].value.match, w))
{
- if (w->protocols & CompWindowProtocolTakeFocusMask)
- {
- ww->protocolSetMask |= (w->protocols &
- CompWindowProtocolTakeFocusMask);
- newProtocol = w->protocols & ~CompWindowProtocolTakeFocusMask;
- ww->oldInputHint = w->inputHint;
- w->inputHint = FALSE;
- }
+ noFocus = FALSE;
}
- else if (ww->oldInputHint ||
- (ww->protocolSetMask & CompWindowProtocolTakeFocusMask))
+ else
{
- newProtocol = w->protocols |
- (ww->protocolSetMask & CompWindowProtocolTakeFocusMask);
- ww->protocolSetMask &= ~CompWindowProtocolTakeFocusMask;
- w->inputHint = ww->oldInputHint;
+ int opt = WINRULES_SCREEN_OPTION_NOFOCUS_MATCH;
+
+ WINRULES_SCREEN (w->screen);
+
+ noFocus = matchEval (&ws->opt[opt].value.match, w);
}
- if (newProtocol != w->protocols)
- winrulesSetProtocols (w->screen->display, newProtocol, w->id);
+ ww->noFocus = noFocus;
+
+ return noFocus;
}
static void
@@ -417,7 +388,7 @@ winrulesSetScreenOption (CompPlugin *plugin,
CompWindow *w;
for (w = screen->windows; w; w = w->next)
- winrulesSetNoFocus (w, WINRULES_SCREEN_OPTION_NOFOCUS_MATCH);
+ winrulesCheckNoFocus (w);
return TRUE;
}
@@ -530,7 +501,9 @@ static void
winrulesHandleEvent (CompDisplay *d,
XEvent *event)
{
- CompWindow *w;
+ CompWindow *w;
+ Bool inputHint;
+ unsigned int protocols;
WINRULES_DISPLAY (d);
@@ -539,7 +512,16 @@ winrulesHandleEvent (CompDisplay *d,
w = findWindowAtDisplay (d, event->xmap.window);
if (w)
{
- winrulesSetNoFocus (w, WINRULES_SCREEN_OPTION_NOFOCUS_MATCH);
+ if (winrulesCheckNoFocus (w))
+ {
+ /* make sure the core MapRequest handler doesn't give
+ focus to the window */
+ inputHint = w->inputHint;
+ protocols = w->protocols;
+
+ w->inputHint = FALSE;
+ w->protocols &= ~CompWindowProtocolTakeFocusMask;
+ }
winrulesApplyRules (w);
}
}
@@ -547,20 +529,51 @@ winrulesHandleEvent (CompDisplay *d,
UNWRAP (wd, d, handleEvent);
(*d->handleEvent) (d, event);
WRAP (wd, d, handleEvent, winrulesHandleEvent);
+
+ if (w && event->type == MapRequest)
+ {
+ w->inputHint = inputHint;
+ w->protocols = protocols;
+ }
}
+static Bool
+winrulesFocusWindow (CompWindow *w)
+{
+ CompScreen *s = w->screen;
+ Bool status;
+
+ WINRULES_WINDOW (w);
+
+ if (ww->noFocus)
+ {
+ status = FALSE;
+ }
+ else
+ {
+ WINRULES_SCREEN (s);
+
+ UNWRAP (ws, s, focusWindow);
+ status = (*s->focusWindow) (w);
+ WRAP (ws, s, focusWindow, winrulesFocusWindow);
+ }
+
+ return status;
+}
static void
winrulesGetAllowedActionsForWindow (CompWindow *w,
unsigned int *setActions,
unsigned int *clearActions)
{
- WINRULES_SCREEN (w->screen);
+ CompScreen *s = w->screen;
+
+ WINRULES_SCREEN (s);
WINRULES_WINDOW (w);
- UNWRAP (ws, w->screen, getAllowedActionsForWindow);
- (*w->screen->getAllowedActionsForWindow) (w, setActions, clearActions);
- WRAP (ws, w->screen, getAllowedActionsForWindow,
- winrulesGetAllowedActionsForWindow);
+ UNWRAP (ws, s, getAllowedActionsForWindow);
+ (*s->getAllowedActionsForWindow) (w, setActions, clearActions);
+ WRAP (ws, s, getAllowedActionsForWindow,
+ winrulesGetAllowedActionsForWindow);
*clearActions |= ~ww->allowedActions;
}
@@ -692,6 +705,7 @@ winrulesInitScreen (CompPlugin *p,
WRAP (ws, s, getAllowedActionsForWindow,
winrulesGetAllowedActionsForWindow);
+ WRAP (ws, s, focusWindow, winrulesFocusWindow);
s->base.privates[wd->screenPrivateIndex].ptr = ws;
@@ -705,6 +719,7 @@ winrulesFiniScreen (CompPlugin *p,
WINRULES_SCREEN (s);
UNWRAP (ws, s, getAllowedActionsForWindow);
+ UNWRAP (ws, s, focusWindow);
freeWindowPrivateIndex(s, ws->windowPrivateIndex);
@@ -725,13 +740,11 @@ winrulesInitWindow (CompPlugin *p,
if (!ww)
return FALSE;
- ww->stateSetMask = 0;
- ww->protocolSetMask = 0;
-
+ ww->stateSetMask = 0;
ww->allowedActions = ~0;
- ww->hasAlpha = w->alpha;
- ww->oldInputHint = w->inputHint;
+ ww->hasAlpha = w->alpha;
+ ww->noFocus = FALSE;
w->base.privates[ws->windowPrivateIndex].ptr = ww;