[compiz] [PATCH] Extra Notifications
Mike Dransfield
mike at blueroot.co.uk
Mon Oct 16 05:41:45 PDT 2006
David Reveman wrote:
> Some notification functions like these might be very nice to have. I'm
> not sure how useful Create and Destroy notifies are, in general plugins
> should never trigger on Create or Destroy notifies, at least not for any
> animations. I think that wrapping handleEvent and masking of
> DestroyNotify/CreateNotify events is efficient for those plugins that
> actually need to be aware of creation and destruction of windows.
>
I have changed these functions to be called windowNewNotify and
windowCloseNotify, they are called just after the first map after a
create and
before the last unmap after a destroy. This hopefully will make it easy
to see
newly mapped windows. This could be used by pagers and taskbars. Window
animation effect plugins can use these to help keep their code clean.
> Unmap, Map, Minimize, Unminimize, Shade, Unshade notification functions
> could be very useful. However it's not obvious how to implement them...
> The tricky part is to figure out when these functions should be called.
> For Map, Unshade and Unminimize functions to be useful for plugins that
> want to do animations, they should be called when the window is mapped
> and content is available so it can be rendered properly. Unmap, Shade
> and Minimize can probably be called immediately, however while adding
> these functions we probably want to rethink the way plugins currently
> keep references to unmapped windows. It's currently not possible to keep
> a reference to an unmapped window after it's mapped again. We need the
> ability to do this to avoid the flicker you currently get when e.g.
> quickly shading and unshading a window.
>
>
I have changed my functions to be called when the window is mapped, I
also added shade and unshade but I got slightly confused by the shade code
so it might not be right. It seems like when a window is shaded it is
also resized
to 0 height.
While digging around I noticed that the StateChange notifications are
sent when
the window is unmapped, should these also be changed so that they are sent
when the window is still mapped?
Changing the way compiz handles unmapped windows is a little beyond me at
the moment so I have left that part. My initial thoughts are that when
a window
is unmapped a new CompUnmappedWindow could be created which would
contain the basic information that could allow a plugin coder to access the
pixmap etc.
Animation actually crashes if you quickly shade and unshade, I assume that
it is trying to access this non-existent window.
> We probably don't want Unmap and Minimize functions to both be called
> when a window is minimized...
Should I also remove the extra state change notifys that you get when
minimizing and unshading?
-------------- next part --------------
diff --git a/include/compiz.h b/include/compiz.h
index 61a9de5..35f7361 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -1245,6 +1245,14 @@ typedef void (*SetWindowScaleProc) (Comp
typedef Bool (*FocusWindowProc) (CompWindow *window);
+typedef void (*WindowNewNotifyProc) (CompWindow *window);
+
+typedef void (*WindowCloseNotifyProc) (CompWindow *window);
+
+typedef void (*WindowMapNotifyProc) (CompWindow *window);
+
+typedef void (*WindowUnmapNotifyProc) (CompWindow *window);
+
typedef void (*WindowResizeNotifyProc) (CompWindow *window);
typedef void (*WindowMoveNotifyProc) (CompWindow *window,
@@ -1265,6 +1273,14 @@ typedef void (*WindowGrabNotifyProc) (Co
typedef void (*WindowUngrabNotifyProc) (CompWindow *window);
+typedef void (*WindowMinimizeNotifyProc) (CompWindow *window);
+
+typedef void (*WindowUnminimizeNotifyProc) (CompWindow *window);
+
+typedef void (*WindowShadeNotifyProc) (CompWindow *window);
+
+typedef void (*WindowUnshadeNotifyProc) (CompWindow *window);
+
typedef void (*WindowStateChangeNotifyProc) (CompWindow *window);
#define COMP_SCREEN_DAMAGE_PENDING_MASK (1 << 0)
@@ -1497,10 +1513,18 @@ struct _CompScreen {
FocusWindowProc focusWindow;
SetWindowScaleProc setWindowScale;
- WindowResizeNotifyProc windowResizeNotify;
- WindowMoveNotifyProc windowMoveNotify;
- WindowGrabNotifyProc windowGrabNotify;
- WindowUngrabNotifyProc windowUngrabNotify;
+ WindowNewNotifyProc windowNewNotify;
+ WindowCloseNotifyProc windowCloseNotify;
+ WindowMapNotifyProc windowMapNotify;
+ WindowUnmapNotifyProc windowUnmapNotify;
+ WindowResizeNotifyProc windowResizeNotify;
+ WindowMoveNotifyProc windowMoveNotify;
+ WindowGrabNotifyProc windowGrabNotify;
+ WindowUngrabNotifyProc windowUngrabNotify;
+ WindowMinimizeNotifyProc windowMinimizeNotify;
+ WindowUnminimizeNotifyProc windowUnminimizeNotify;
+ WindowShadeNotifyProc windowShadeNotify;
+ WindowUnshadeNotifyProc windowUnshadeNotify;
WindowStateChangeNotifyProc windowStateChangeNotify;
@@ -1770,6 +1794,12 @@ struct _CompWindow {
Bool inShowDesktopMode;
Bool shaded;
Bool hidden;
+ /* used to stop unmap notifications and make sure
+ notifications are sent when the window is still mapped */
+ Bool wasMinimized;
+ Bool wasShaded;
+ Bool wasCreated;
+ Bool wasClosed;
int pendingUnmaps;
@@ -2012,6 +2042,18 @@ Bool
focusWindow (CompWindow *w);
void
+windowNewNotify (CompWindow *w);
+
+void
+windowCloseNotify (CompWindow *w);
+
+void
+windowMapNotify (CompWindow *w);
+
+void
+windowUnmapNotify (CompWindow *w);
+
+void
windowResizeNotify (CompWindow *w);
void
@@ -2031,6 +2073,18 @@ void
windowUngrabNotify (CompWindow *w);
void
+windowMinimizeNotify (CompWindow *w);
+
+void
+windowUnminimizeNotify (CompWindow *w);
+
+void
+windowShadeNotify (CompWindow *w);
+
+void
+windowUnshadeNotify (CompWindow *w);
+
+void
windowStateChangeNotify (CompWindow *w);
void
-------------- next part --------------
diff --git a/src/screen.c b/src/screen.c
index 5a1c145..c9ded83 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -1180,10 +1180,18 @@ addScreen (CompDisplay *display,
s->focusWindow = focusWindow;
s->setWindowScale = setWindowScale;
- s->windowResizeNotify = windowResizeNotify;
- s->windowMoveNotify = windowMoveNotify;
- s->windowGrabNotify = windowGrabNotify;
- s->windowUngrabNotify = windowUngrabNotify;
+ s->windowResizeNotify = windowResizeNotify;
+ s->windowMoveNotify = windowMoveNotify;
+ s->windowGrabNotify = windowGrabNotify;
+ s->windowUngrabNotify = windowUngrabNotify;
+ s->windowNewNotify = windowNewNotify;
+ s->windowCloseNotify = windowCloseNotify;
+ s->windowMapNotify = windowMapNotify;
+ s->windowUnmapNotify = windowUnmapNotify;
+ s->windowMinimizeNotify = windowMinimizeNotify;
+ s->windowUnminimizeNotify = windowUnminimizeNotify;
+ s->windowShadeNotify = windowShadeNotify;
+ s->windowUnshadeNotify = windowUnshadeNotify;
s->windowStateChangeNotify = windowStateChangeNotify;
-------------- next part --------------
diff --git a/src/window.c b/src/window.c
index 3346d89..5544bca 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1510,6 +1510,11 @@ addWindow (CompScreen *screen,
w->shaded = FALSE;
w->hidden = FALSE;
+ w->wasMinimized = FALSE;
+ w->wasShaded = FALSE;
+ w->wasCreated = TRUE;
+ w->wasClosed = FALSE;
+
w->initialViewportX = screen->x;
w->initialViewportY = screen->y;
@@ -1943,6 +1948,29 @@ mapWindow (CompWindow *w)
w->attrib.width, ++w->attrib.height - 1,
w->attrib.border_width);
}
+
+ /* send notify for newly created and mapped windows */
+ if (w->wasMinimized)
+ {
+ (*w->screen->windowUnminimizeNotify) (w);
+ w->wasMinimized = FALSE;
+ }
+ else if (w->wasShaded)
+ {
+ w->wasShaded = FALSE;
+ (*w->screen->windowUnshadeNotify) (w);
+ }
+ else if ((w->attrib.map_state == IsViewable) &&
+ w->wasCreated)
+ {
+ w->wasCreated = FALSE;
+ (*w->screen->windowNewNotify) (w);
+ }
+ else
+ {
+ (*w->screen->windowMapNotify) (w);
+ }
+
}
void
@@ -1950,7 +1978,12 @@ unmapWindow (CompWindow *w)
{
if (w->mapNum)
{
- if (w->frame && !w->shaded)
+ if (!w->minimized && !w->wasClosed && !w->shaded)
+ (*w->screen->windowUnmapNotify) (w);
+
+ if (w->shaded)
+ (*w->screen->windowShadeNotify) (w);
+ else if (w->frame)
XUnmapWindow (w->screen->display->display, w->frame);
w->mapNum = 0;
@@ -1984,6 +2017,7 @@ unmapWindow (CompWindow *w)
updateWorkareaForScreen (w->screen);
updateClientListForScreen (w->screen);
+
}
static int
@@ -2088,7 +2122,7 @@ resizeWindow (CompWindow *w,
if (w->mapNum)
updateWindowRegion (w);
- (*w->screen->windowResizeNotify) (w);
+ (*w->screen->windowResizeNotify) (w);
addWindowDamage (w);
@@ -2355,6 +2389,26 @@ focusWindow (CompWindow *w)
}
void
+windowNewNotify (CompWindow *w)
+{
+}
+
+void
+windowCloseNotify (CompWindow *w)
+{
+}
+
+void
+windowMapNotify (CompWindow *w)
+{
+}
+
+void
+windowUnmapNotify (CompWindow *w)
+{
+}
+
+void
windowResizeNotify (CompWindow *w)
{
}
@@ -2382,6 +2436,26 @@ windowUngrabNotify (CompWindow *w)
}
void
+windowMinimizeNotify (CompWindow *w)
+{
+}
+
+void
+windowUnminimizeNotify (CompWindow *w)
+{
+}
+
+void
+windowShadeNotify (CompWindow *w)
+{
+}
+
+void
+windowUnshadeNotify (CompWindow *w)
+{
+}
+
+void
windowStateChangeNotify (CompWindow *w)
{
}
@@ -3476,6 +3550,9 @@ closeWindow (CompWindow *w,
if (w->alive)
{
+ (*w->screen->windowCloseNotify) (w);
+ w->wasClosed = TRUE;
+
if (w->protocols & CompWindowProtocolDeleteMask)
{
XEvent ev;
@@ -3672,6 +3749,7 @@ hideWindow (CompWindow *w)
{
if (w->state & CompWindowStateShadedMask)
{
+ w->wasShaded = TRUE;
w->shaded = TRUE;
}
else
@@ -3769,10 +3847,14 @@ minimizeWindow (CompWindow *w)
if (!w->minimized)
{
+ (*w->screen->windowMinimizeNotify) (w);
+
w->minimized = TRUE;
forEachWindowOnScreen (w->screen, minimizeTransients, (void *) w);
+ w->wasMinimized = TRUE;
+
hideWindow (w);
}
}
More information about the compiz
mailing list