Browse Source

Fix manage of sticky windows

David Delassus 12 years ago
parent
commit
151dc9f9f1
6 changed files with 54 additions and 13 deletions
  1. 1 3
      src/client.c
  2. 2 1
      src/event.c
  3. 49 6
      src/ewmh.c
  4. 1 1
      src/ewmh.h
  5. 1 1
      src/layout.c
  6. 0 1
      src/wmfs.h

+ 1 - 3
src/client.c

@@ -972,14 +972,12 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
           client_apply_rule(c);
      }
 
-     ewmh_manage_state_sticky(c);
-
      /*
       * Conf option set per client, for possibility
       * to config only one client
       */
      c->border = c->theme->client_border_width;
-     if(!(c->tbarw = c->theme->client_titlebar_width) || (c->flags & CLIENT_STICKY))
+     if(!(c->tbarw = c->theme->client_titlebar_width))
           c->tbarw = c->border;
 
      c->ncol = c->theme->client_n;

+ 2 - 1
src/event.c

@@ -245,7 +245,8 @@ event_maprequest(XEvent *e)
      /* Which windows to manage */
      if(!XGetWindowAttributes(EVDPY(e), ev->window, &at)
         || at.override_redirect
-        || ewmh_manage_window_type_desktop(ev->window))
+        || ewmh_manage_window_type_desktop(ev->window)
+        || ewmh_manage_state_sticky(ev->window))
           return;
 
      if(!client_gb_win(ev->window))

+ 49 - 6
src/ewmh.c

@@ -230,15 +230,16 @@ ewmh_manage_state(long data[], struct client *c)
 
 }
 
-void
-ewmh_manage_state_sticky(struct client *c)
+bool
+ewmh_manage_state_sticky(Window win)
 {
      Atom *atom, rf;
      int f;
      unsigned long n, il, i;
      unsigned char *data = NULL;
+     bool is_sticky = false;
 
-     if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
+     if(XGetWindowProperty(W->dpy, win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false,
                            XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
      {
           atom = (Atom*)data;
@@ -248,17 +249,59 @@ ewmh_manage_state_sticky(struct client *c)
                /* manage _NET_WM_STATE_STICKY */
                if(atom[i] == W->net_atom[net_wm_state_sticky])
                {
-                    c->flags |= CLIENT_STICKY;
-                    c->flags |= CLIENT_FREE;
+                    XWindowAttributes at;
+
+                    XMapWindow(W->dpy, win);
+                    XMapSubwindows(W->dpy, win);
+
+                    if(XGetWindowAttributes(W->dpy, win, &at))
+                    {
+                         struct geo g;
+
+                         if(at.x < W->screen->ugeo.x)
+                              g.x = W->screen->ugeo.x;
+                         else if((at.x + at.width) > W->screen->ugeo.w)
+                              g.x = W->screen->ugeo.w - at.width;
+                         else
+                              g.x = at.x;
 
-                    client_place_at_mouse(c);
+                         if(at.y < W->screen->ugeo.y)
+                              g.y = W->screen->ugeo.y;
+                         else if((at.y + at.height) > W->screen->ugeo.h)
+                              g.y = W->screen->ugeo.h - at.height;
+                         else
+                              g.y = at.y;
 
+                         XMoveWindow(W->dpy, win, g.x, g.y);
+                    }
+
+                    if(W->client)
+                    {
+                         XUngrabButton(W->dpy, AnyButton, AnyModifier, W->client->win);
+                         XGrabButton(W->dpy, AnyButton, AnyModifier, W->client->win, False,
+                                   ButtonMask, GrabModeAsync, GrabModeSync, None, None);
+
+                         client_frame_update(W->client, &W->client->ncol);
+
+                         W->client = NULL;
+                    }
+
+
+                    XRaiseWindow(W->dpy, win);
+
+                    XSetInputFocus(W->dpy, win, RevertToPointerRoot, CurrentTime);
+                    XChangeProperty(W->dpy, W->root, W->net_atom[net_active_window], XA_WINDOW, 32,
+                                    PropModeReplace, (unsigned char *)&win, 1);
+
+                    is_sticky = true;
                     break;
                }
           }
 
           XFree(data);
      }
+
+     return is_sticky;
 }
 
 void

+ 1 - 1
src/ewmh.h

@@ -124,7 +124,7 @@ void ewmh_get_client_list(void);
 long ewmh_get_xembed_state(Window win);
 void ewmh_update_wmfs_props(void);
 void ewmh_manage_state(long data[], struct client *c);
-void ewmh_manage_state_sticky(struct client *c);
+bool ewmh_manage_state_sticky(Window win);
 void ewmh_manage_window_type(struct client *c);
 bool ewmh_manage_window_type_desktop(Window win);
 

+ 1 - 1
src/layout.c

@@ -631,7 +631,7 @@ layout_client(struct client *c)
           return;
      }
 
-     if(c->flags & (CLIENT_FREE | CLIENT_STICKY))
+     if(c->flags & CLIENT_FREE)
      {
           layout_split_arrange_closed(c);
           c->flags ^= CLIENT_TILED;

+ 0 - 1
src/wmfs.h

@@ -217,7 +217,6 @@ struct client
 #define CLIENT_TILED         0x2000
 #define CLIENT_MOUSE         0x4000
 #define CLIENT_IGNORE_TAG    0x8000
-#define CLIENT_STICKY        0x10000
      Flags flags;
      Window win, frame, tmp;
      SLIST_ENTRY(client) next;   /* Global list */