Yaakov (Cygwin Ports) wrote:
Jon,

Following up on our discussion about multiwindow not honouring
_NET_WM_STATE_SKIP_TASKBAR.  The attached patch was what I had in mind
but it has no effect.  I'm posting this now to at least start the
discussion.

You may wish to refer to the FD.o EWMH specs:

http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html

Yaakov,

Here's a slightly improved version of that patch, and working version of the small testcase you pointed out to me.

Sadly, doesn't work quite as well as it might: to remove a window from the taskbar, not only do you have to remove the WS_EX_APPWINDOW style, but also add the WS_EX_TOOLWINDOW style, which changes the size of the title bar etc.

So this might look ok for some title-bar less dialog-style windows, but looks a bit odd otherwise.

Anyhow, try it out and see what you think.
Process _NET_WM_STATE_SKIP_TASKBAR hint in multiwindow mode.

---
 xserver/hw/xwin/winmultiwindowwm.c      |   43 ++
+++++++++++++++++++++++-------
 xserver/hw/xwin/winmultiwindowwm.c      |   45 ++++++++++++++++++++++++--------
 xserver/hw/xwin/winmultiwindowwndproc.c |   28 ++++++++-----------
 2 files changed, 47 insertions(+), 26 deletions(-)

Index: xorg-server-1.5.3/xserver/hw/xwin/winmultiwindowwm.c
===================================================================
--- xorg-server-1.5.3.orig/xserver/hw/xwin/winmultiwindowwm.c
+++ xorg-server-1.5.3/xserver/hw/xwin/winmultiwindowwm.c
@@ -1470,6 +1470,8 @@ winDeinitMultiWindowWM ()
 #define HINT_BORDER    (1L<<1)
 #define HINT_SIZEBOX   (1l<<2)
 #define HINT_CAPTION   (1l<<3)
+/* Windows extended window styles */
+#define HINT_SKIPTASKBAR       (1L<<0)
 /* These two are used on their own */
 #define HINT_MAX       (1L<<0)
 #define HINT_MIN       (1L<<1)
@@ -1480,7 +1482,7 @@ winApplyHints (Display *pDisplay, Window
   static Atom  windowState, motif_wm_hints, windowType;
   Atom         type, *pAtom = NULL;
   int          format;
-  unsigned long        hint = 0, maxmin = 0, rcStyle, nitems = 0 , left = 0;
+  unsigned long        hint = 0, exHint = 0, maxmin = 0, rcStyle, nitems = 0 , 
left = 0;
   WindowPtr    pWin = GetProp (hWnd, WIN_WINDOW_PROP);
 
   if (!hWnd) return;
@@ -1491,22 +1493,31 @@ winApplyHints (Display *pDisplay, Window
   if (windowType == None) windowType = XInternAtom(pDisplay, 
"_NET_WM_WINDOW_TYPE", False);
 
   if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
-                        1L, False, XA_ATOM, &type, &format,
+                        MAXINT, False, XA_ATOM, &type, &format,
                         &nitems, &left, (unsigned char **)&pAtom) == Success)
   {
-    if (pAtom && nitems == 1)
+    if (pAtom)
     {
-      static Atom hiddenState, fullscreenState, belowState, aboveState;
+      static Atom skiptaskbarState, hiddenState, fullscreenState, belowState, 
aboveState;
+
+      if (skiptaskbarState == None) skiptaskbarState = XInternAtom(pDisplay, 
"_NET_WM_STATE_SKIP_TASKBAR", False);
       if (hiddenState == None) hiddenState = XInternAtom(pDisplay, 
"_NET_WM_STATE_HIDDEN", False);
       if (fullscreenState == None) fullscreenState = XInternAtom(pDisplay, 
"_NET_WM_STATE_FULLSCREEN", False);
       if (belowState == None) belowState = XInternAtom(pDisplay, 
"_NET_WM_STATE_BELOW", False);
       if (aboveState == None) aboveState = XInternAtom(pDisplay, 
"_NET_WM_STATE_ABOVE", False);
-      if (*pAtom == hiddenState) maxmin |= HINT_MIN;
-      else if (*pAtom == fullscreenState) maxmin |= HINT_MAX;
-      if (*pAtom == belowState) *zstyle = HWND_BOTTOM;
-      else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST;
+
+      unsigned long i;
+      for (i = 0; i < nitems; i++)
+       {
+         if (*pAtom == skiptaskbarState) exHint |= HINT_SKIPTASKBAR;
+         if (*pAtom == hiddenState) maxmin |= HINT_MIN;
+         else if (*pAtom == fullscreenState) maxmin |= HINT_MAX;
+         if (*pAtom == belowState) *zstyle = HWND_BOTTOM;
+         else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST;
+       }
+
+      XFree(pAtom);
     }
-    if (pAtom) XFree(pAtom);
   }
 
   nitems = left = 0;
@@ -1547,6 +1558,17 @@ winApplyHints (Display *pDisplay, Window
     if (pAtom) XFree(pAtom);
   }
 
+  /* Transient windows which are transient for non-root window shouldn't be in 
taskbar */
+  /* XXX: perhaps? */
+  {
+    WindowPtr pDaddy;
+    if (winMultiWindowGetTransientFor(pWin, &pDaddy))
+      {
+       if (pDaddy)
+         exHint |= HINT_SKIPTASKBAR;
+      }
+  }
+
   /* Apply Styles, overriding hint settings from above */
   rcStyle = winOverrideStyle((unsigned long)pWin);
   if (rcStyle & STYLE_TOPMOST) *zstyle = HWND_TOPMOST;
@@ -1573,7 +1595,10 @@ winApplyHints (Display *pDisplay, Window
                        ((hint & HINT_SIZEBOX) ? (GetParent(hWnd) ? 0 : 
WS_SIZEBOX) : 0) |
                        ((hint & HINT_CAPTION) ? WS_CAPTION : 0));
 
-  return;
+  if (exHint & HINT_SKIPTASKBAR)
+    SetWindowLongPtr(hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
+  else
+    SetWindowLongPtr(hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
 }
 
 void
Index: xorg-server-1.5.3/xserver/hw/xwin/winmultiwindowwndproc.c
===================================================================
--- xorg-server-1.5.3.orig/xserver/hw/xwin/winmultiwindowwndproc.c
+++ xorg-server-1.5.3/xserver/hw/xwin/winmultiwindowwndproc.c
@@ -866,24 +866,20 @@ winTopLevelWindowProc (HWND hwnd, UINT m
          /* Flag that this window needs to be made active when clicked */
          SetProp (hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
 
-         if (!(GetWindowLongPtr (hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW))
-           {
-             HWND              zstyle = HWND_NOTOPMOST;
-
-             /* Set the window extended style flags */
-             SetWindowLongPtr (hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
+         HWND zstyle = HWND_NOTOPMOST;
 
-             /* Set the transient style flags */
-             if (GetParent(hwnd)) SetWindowLongPtr (hwnd, GWL_STYLE,
-                  WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | WS_CLIPCHILDREN | 
WS_CLIPSIBLINGS);
-             /* Set the window standard style flags */
-             else SetWindowLongPtr (hwnd, GWL_STYLE,
-                  (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | 
WS_CLIPSIBLINGS)
-                  & ~WS_CAPTION & ~WS_SIZEBOX);
+         /* Set the transient style flags */
+         if (GetParent(hwnd))
+           /* Set the window standard style flags */
+           SetWindowLongPtr (hwnd, GWL_STYLE,
+                             WS_POPUP | WS_OVERLAPPED | WS_SYSMENU | 
WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+         else
+           SetWindowLongPtr (hwnd, GWL_STYLE,
+                             (WS_POPUP | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN 
| WS_CLIPSIBLINGS)
+                             & ~WS_CAPTION & ~WS_SIZEBOX);
 
-             winUpdateWindowPosition (hwnd, FALSE, &zstyle);
-             SetForegroundWindow (hwnd);
-           }
+         winUpdateWindowPosition (hwnd, FALSE, &zstyle);
+         SetForegroundWindow (hwnd);
          wmMsg.msg = WM_WM_MAP;
        }
       else /* It is an overridden window so make it top of Z stack */
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <assert.h>
#include <stdio.h>

//  gcc net_wm_state_skip_taskbar.c -lX11
//
// test case for _NET_WM_STATE_SKIP_TASKBAR
//
int main()
{
  // Open the display
  Display *dpy = XOpenDisplay(NULL);
  assert(dpy);

  // Get some colors
  int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
  int whiteColor = WhitePixel(dpy, DefaultScreen(dpy));

  // Create the window
  Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 200, 100, 
0, blackColor, blackColor);
  XMapWindow(dpy, w);

  Atom skip_taskbar = XInternAtom(dpy, "_NET_WM_STATE_SKIP_TASKBAR",False);
  Atom net_wm_state = XInternAtom(dpy, "_NET_WM_STATE",False);

  XChangeProperty(dpy, w, net_wm_state, XA_ATOM, 32,
                  PropModeAppend, (unsigned char *)&skip_taskbar, 1);

  XFlush(dpy);

  // Wait for ever
  while (1)
    {
      sleep(1);
    }
}

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://x.cygwin.com/docs/
FAQ:                   http://x.cygwin.com/docs/faq/

Reply via email to