[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