summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Baumann <dannybaumann@web.de>2008-04-29 09:30:08 +0200
committerDanny Baumann <dannybaumann@web.de>2008-04-29 09:30:08 +0200
commita113f9953ef3c8daf9401d76d6fff55c1ed50422 (patch)
tree4062b35ba0d89b5f062b1973a53010c29c2257f6
parent92878369ff9d8344f8bfad172ef4ea616380da8a (diff)
downloadextrawm-a113f9953ef3c8daf9401d76d6fff55c1ed50422.tar.gz
extrawm-a113f9953ef3c8daf9401d76d6fff55c1ed50422.tar.bz2
Added binding that allows cycling all "demands attention" windows.
-rw-r--r--extrawm.c203
-rw-r--r--extrawm.xml.in4
2 files changed, 205 insertions, 2 deletions
diff --git a/extrawm.c b/extrawm.c
index cbeba61..6b214b2 100644
--- a/extrawm.c
+++ b/extrawm.c
@@ -25,6 +25,95 @@
#include <compiz-core.h>
#include "extrawm_options.h"
+static int ExtraWMDisplayPrivateIndex;
+
+typedef struct _DemandsAttentionWindow {
+ CompWindow *w;
+ struct _DemandsAttentionWindow *next;
+} DemandsAttentionWindow;
+
+typedef struct _ExtraWMDisplay {
+ int screenPrivateIndex;
+} ExtraWMDisplay;
+
+typedef struct _ExtraWMScreen {
+ WindowStateChangeNotifyProc windowStateChangeNotify;
+
+ DemandsAttentionWindow *attentionWindows;
+} ExtraWMScreen;
+
+#define EXTRAWM_DISPLAY(d) PLUGIN_DISPLAY(d, ExtraWM, e)
+#define EXTRAWM_SCREEN(s) PLUGIN_SCREEN(s, ExtraWM, e)
+
+static void
+addAttentionWindow (CompWindow *w)
+{
+ DemandsAttentionWindow *dw;
+
+ EXTRAWM_SCREEN (w->screen);
+
+ dw = malloc (sizeof (DemandsAttentionWindow));
+ if (!dw)
+ return;
+
+ dw->w = w;
+ dw->next = es->attentionWindows;
+ es->attentionWindows = dw;
+}
+
+static void
+removeAttentionWindow (CompWindow *w)
+{
+ DemandsAttentionWindow *dw, *ldw;
+
+ EXTRAWM_SCREEN (w->screen);
+
+ for (dw = es->attentionWindows, ldw = NULL; dw; dw = dw->next)
+ {
+ if (w == dw->w)
+ {
+ if (ldw)
+ ldw->next = dw->next;
+ else
+ es->attentionWindows = dw->next;
+
+ free (dw);
+ break;
+ }
+
+ ldw = dw;
+ }
+}
+
+static Bool
+activateDemandsAttention (CompDisplay *d,
+ CompAction *action,
+ CompActionState state,
+ CompOption *option,
+ int nOption)
+{
+ Window xid;
+ CompScreen *s;
+
+ xid = getIntOptionNamed (option, nOption, "root", None);
+ s = findScreenAtDisplay (d, xid);
+
+ if (s)
+ {
+ EXTRAWM_SCREEN (s);
+
+ if (es->attentionWindows)
+ {
+ CompWindow *w = es->attentionWindows->w;
+
+ removeAttentionWindow (w);
+ (*w->screen->activateWindow) (w);
+ }
+ }
+
+ return FALSE;
+}
+
static Bool
activateWin (CompDisplay *d,
CompAction *action,
@@ -156,52 +245,162 @@ toggleSticky (CompDisplay *d,
return TRUE;
}
+static void
+extraWMWindowStateChangeNotify (CompWindow *w,
+ unsigned int lastState)
+{
+ CompScreen *s = w->screen;
+
+ EXTRAWM_SCREEN (s);
+
+ UNWRAP (es, s, windowStateChangeNotify);
+ (*s->windowStateChangeNotify) (w, lastState);
+ WRAP (es, s, windowStateChangeNotify, extraWMWindowStateChangeNotify);
+
+ if ((w->state ^ lastState) & CompWindowStateDemandsAttentionMask)
+ {
+ if (w->state & CompWindowStateDemandsAttentionMask)
+ addAttentionWindow (w);
+ else
+ removeAttentionWindow (w);
+ }
+}
+
static Bool
extraWMInit (CompPlugin *p)
{
+ ExtraWMDisplayPrivateIndex = allocateDisplayPrivateIndex ();
+ if (ExtraWMDisplayPrivateIndex < 0)
+ return FALSE;
+
return TRUE;
}
static void
extraWMFini (CompPlugin *p)
{
+ freeDisplayPrivateIndex (ExtraWMDisplayPrivateIndex);
}
static Bool
extraWMInitDisplay (CompPlugin *p,
CompDisplay *d)
{
+ ExtraWMDisplay *ed;
+
if (!checkPluginABI ("core", CORE_ABIVERSION))
return FALSE;
+ ed = malloc (sizeof (ExtraWMDisplay));
+ if (!ed)
+ return FALSE;
+
+ ed->screenPrivateIndex = allocateScreenPrivateIndex (d);
+ if (ed->screenPrivateIndex < 0)
+ {
+ free (ed);
+ return FALSE;
+ }
+
extrawmSetToggleRedirectKeyInitiate (d, toggleRedirect);
extrawmSetToggleAlwaysOnTopKeyInitiate (d, toggleAlwaysOnTop);
extrawmSetToggleStickyKeyInitiate (d, toggleSticky);
extrawmSetToggleFullscreenKeyInitiate (d, toggleFullscreen);
extrawmSetActivateInitiate (d, activateWin);
+ extrawmSetActivateDemandsAttentionInitiate (d, activateDemandsAttention);
+
+ d->base.privates[ExtraWMDisplayPrivateIndex].ptr = ed;
return TRUE;
}
+static void
+extraWMFiniDisplay (CompPlugin *p,
+ CompDisplay *d)
+{
+ EXTRAWM_DISPLAY (d);
+
+ freeScreenPrivateIndex (d, ed->screenPrivateIndex);
+
+ free (ed);
+}
+
+static Bool
+extraWMInitScreen (CompPlugin *p,
+ CompScreen *s)
+{
+ ExtraWMScreen *es;
+
+ EXTRAWM_DISPLAY (s->display);
+
+ es = malloc (sizeof (ExtraWMScreen));
+ if (!es)
+ return FALSE;
+
+ es->attentionWindows = NULL;
+
+ WRAP (es, s, windowStateChangeNotify, extraWMWindowStateChangeNotify);
+
+ s->base.privates[ed->screenPrivateIndex].ptr = es;
+
+ return TRUE;
+}
+
+static void
+extraWMFiniScreen (CompPlugin *p,
+ CompScreen *s)
+{
+ EXTRAWM_SCREEN (s);
+
+ UNWRAP (es, s, windowStateChangeNotify);
+
+ while (es->attentionWindows)
+ removeAttentionWindow (es->attentionWindows->w);
+
+ free (es);
+}
+
+static void
+extraWMFiniWindow (CompPlugin *p,
+ CompWindow *w)
+{
+ removeAttentionWindow (w);
+}
+
static CompBool
extraWMInitObject (CompPlugin *p,
CompObject *o)
{
static InitPluginObjectProc dispTab[] = {
(InitPluginObjectProc) 0, /* InitCore */
- (InitPluginObjectProc) extraWMInitDisplay
+ (InitPluginObjectProc) extraWMInitDisplay,
+ (InitPluginObjectProc) extraWMInitScreen
};
RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
}
+static void
+extraWMFiniObject (CompPlugin *p,
+ CompObject *o)
+{
+ static InitPluginObjectProc dispTab[] = {
+ (InitPluginObjectProc) 0, /* InitCore */
+ (InitPluginObjectProc) extraWMFiniDisplay,
+ (InitPluginObjectProc) extraWMFiniScreen,
+ (InitPluginObjectProc) extraWMFiniWindow
+ };
+
+ DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
+}
+
CompPluginVTable extraWMVTable = {
"extrawm",
0,
extraWMInit,
extraWMFini,
extraWMInitObject,
- 0,
+ extraWMFiniObject,
0,
0
};
diff --git a/extrawm.xml.in b/extrawm.xml.in
index e644745..87ae4e5 100644
--- a/extrawm.xml.in
+++ b/extrawm.xml.in
@@ -25,6 +25,10 @@
<_short>Toggle Sticky</_short>
<_long>Toggle window stickyness</_long>
</option>
+ <option name="activate_demands_attention" type="key">
+ <_short>Activate Demanding Attention Window</_short>
+ <_long>Activate next window which has the "demands attention" flag set.</_long>
+ </option>
</display>
</plugin>
</compiz>