about summary refs log tree commit diff
path: root/exwm-manage.el
diff options
context:
space:
mode:
Diffstat (limited to 'exwm-manage.el')
-rw-r--r--exwm-manage.el91
1 files changed, 53 insertions, 38 deletions
diff --git a/exwm-manage.el b/exwm-manage.el
index 79c5405fffe8..b41512c485c0 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -1,7 +1,7 @@
 ;;; exwm-manage.el --- Window Management Module for  -*- lexical-binding: t -*-
 ;;;                    EXWM
 
-;; Copyright (C) 2015-2018 Free Software Foundation, Inc.
+;; Copyright (C) 2015-2019 Free Software Foundation, Inc.
 
 ;; Author: Chris Feng <chris.w.feng@gmail.com>
 
@@ -70,6 +70,7 @@ You can still make the X windows floating afterwards."
                         (const :tag "Prefix keys" prefix-keys)
                         (const :tag "Simulation keys" simulation-keys)
                         (const :tag "Workspace" workspace)
+                        (const :tag "Managed" managed)
                         ;; For forward compatibility.
                         (other))
                        :value-type (sexp :tag "Value" nil))))
@@ -90,6 +91,7 @@ You can still make the X windows floating afterwards."
 (defvar exwm-manage--ping-lock nil
   "Non-nil indicates EXWM is pinging a window.")
 
+(defvar exwm-input--skip-buffer-list-update)
 (defvar exwm-input-prefix-keys)
 (defvar exwm-workspace--current)
 (defvar exwm-workspace--id-struts-alist)
@@ -200,7 +202,8 @@ You can still make the X windows floating afterwards."
         (make-instance 'xcb:ChangeSaveSet
                        :mode xcb:SetMode:Insert
                        :window id))
-    (with-current-buffer (generate-new-buffer "*EXWM*")
+    (with-current-buffer (let ((exwm-input--skip-buffer-list-update t))
+                           (generate-new-buffer "*EXWM*"))
       ;; Keep the oldest X window first.
       (setq exwm--id-buffer-alist
             (nconc exwm--id-buffer-alist `((,id . ,(current-buffer)))))
@@ -214,22 +217,33 @@ You can still make the X windows floating afterwards."
       (exwm--update-hints id)
       (exwm-manage--update-geometry id)
       (exwm-manage--update-mwm-hints id)
-      ;; No need to manage (please check OverrideRedirect outside)
-      (when (or
-             (not
-              (or (not exwm-window-type)
-                  (memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY exwm-window-type)
-                  (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG exwm-window-type)
-                  (memq xcb:Atom:_NET_WM_WINDOW_TYPE_NORMAL exwm-window-type)))
-             ;; Check the _MOTIF_WM_HINTS property.
-             (and (not exwm--mwm-hints-decorations)
-                  (not exwm--hints-input)
-                  ;; Floating windows only
-                  (or exwm-transient-for exwm--fixed-size
-                      (memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY
-                            exwm-window-type)
-                      (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG
-                            exwm-window-type))))
+      (exwm--update-title id)
+      (exwm--update-protocols id)
+      (setq exwm--configurations (exwm-manage--get-configurations))
+      ;; OverrideRedirect is not checked here.
+      (when (and
+             ;; The user has specified to manage it.
+             (not (plist-get exwm--configurations 'managed))
+             (or
+              ;; The user has specified not to manage it.
+              (plist-member exwm--configurations 'managed)
+              ;; This is not a type of X window we can manage.
+              (and exwm-window-type
+                   (not (cl-intersection
+                         exwm-window-type
+                         (list xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY
+                               xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG
+                               xcb:Atom:_NET_WM_WINDOW_TYPE_NORMAL))))
+              ;; Check the _MOTIF_WM_HINTS property to not manage floating X
+              ;; windows without decoration.
+              (and (not exwm--mwm-hints-decorations)
+                   (not exwm--hints-input)
+                   ;; Floating windows only
+                   (or exwm-transient-for exwm--fixed-size
+                       (memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY
+                             exwm-window-type)
+                       (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG
+                             exwm-window-type)))))
         (exwm--log "No need to manage #x%x" id)
         ;; Update struts.
         (when (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DOCK exwm-window-type)
@@ -274,10 +288,10 @@ You can still make the X windows floating afterwards."
                              :stack-mode xcb:StackMode:Below)))
         (xcb:flush exwm--connection)
         (setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
-        (let ((kill-buffer-query-functions nil))
+        (let ((kill-buffer-query-functions nil)
+              (exwm-input--skip-buffer-list-update t))
           (kill-buffer (current-buffer)))
         (throw 'return 'ignored))
-      (setq exwm--configurations (exwm-manage--get-configurations))
       (let ((index (plist-get exwm--configurations 'workspace)))
         (when (and index (< index (length exwm-workspace--list)))
           (setq exwm--frame (elt exwm-workspace--list index))))
@@ -299,8 +313,6 @@ You can still make the X windows floating afterwards."
                            :button button :modifiers xcb:ModMask:Any)))
       (exwm-manage--set-client-list)
       (xcb:flush exwm--connection)
-      (exwm--update-title id)
-      (exwm--update-protocols id)
       (if (plist-member exwm--configurations 'floating)
           ;; User has specified whether it should be floating.
           (if (plist-get exwm--configurations 'floating)
@@ -556,7 +568,7 @@ Would you like to kill it? "
     (with-slots (window x y width height
                         border-width sibling stack-mode value-mask)
         obj
-      (exwm--log "ConfigureRequest from #x%x (#x%x) @%dx%d%+d%+d; \
+      (exwm--log "#x%x (#x%x) @%dx%d%+d%+d; \
 border-width: %d; sibling: #x%x; stack-mode: %d"
                  window value-mask width height x y
                  border-width sibling stack-mode)
@@ -654,7 +666,7 @@ border-width: %d; sibling: #x%x; stack-mode: %d"
             (progn (xcb:+request exwm--connection
                        (make-instance 'xcb:MapWindow :window window))
                    (xcb:flush exwm--connection))
-          (exwm--log "MapRequest from #x%x" window)
+          (exwm--log "#x%x" window)
           (exwm-manage--manage-window window))))))
 
 (defun exwm-manage--on-UnmapNotify (data _synthetic)
@@ -674,11 +686,20 @@ border-width: %d; sibling: #x%x; stack-mode: %d"
         (exwm--log "id=#x%x" window)
         ;; With this we ensure that a "window hierarchy change" happens after
         ;; mapping the window, as some servers (XQuartz) do not generate it.
-        (xcb:+request exwm--connection
-            (make-instance 'xcb:ConfigureWindow
-                           :window window
-                           :value-mask xcb:ConfigWindow:StackMode
-                           :stack-mode xcb:StackMode:Above))
+        (with-current-buffer (exwm--id->buffer window)
+          (if exwm--floating-frame
+              (xcb:+request exwm--connection
+                  (make-instance 'xcb:ConfigureWindow
+                                 :window window
+                                 :value-mask xcb:ConfigWindow:StackMode
+                                 :stack-mode xcb:StackMode:Above))
+            (xcb:+request exwm--connection
+                (make-instance 'xcb:ConfigureWindow
+                               :window window
+                               :value-mask (logior xcb:ConfigWindow:Sibling
+                                                   xcb:ConfigWindow:StackMode)
+                               :sibling exwm--guide-window
+                               :stack-mode xcb:StackMode:Above))))
         (xcb:flush exwm--connection)))))
 
 (defun exwm-manage--on-DestroyNotify (data synthetic)
@@ -687,21 +708,14 @@ border-width: %d; sibling: #x%x; stack-mode: %d"
     (exwm--log)
     (let ((obj (make-instance 'xcb:DestroyNotify)))
       (xcb:unmarshal obj data)
-      (exwm--log "DestroyNotify from #x%x" (slot-value obj 'window))
+      (exwm--log "#x%x" (slot-value obj 'window))
       (exwm-manage--unmanage-window (slot-value obj 'window)))))
 
 (defun exwm-manage--init ()
   "Initialize manage module."
   ;; Intern _MOTIF_WM_HINTS
   (exwm--log)
-  (let ((atom-name "_MOTIF_WM_HINTS"))
-    (setq exwm-manage--_MOTIF_WM_HINTS
-          (slot-value (xcb:+request-unchecked+reply exwm--connection
-                          (make-instance 'xcb:InternAtom
-                                         :only-if-exists 0
-                                         :name-len (length atom-name)
-                                         :name atom-name))
-                      'atom)))
+  (setq exwm-manage--_MOTIF_WM_HINTS (exwm--intern-atom "_MOTIF_WM_HINTS"))
   (add-hook 'after-make-frame-functions #'exwm-manage--add-frame)
   (add-hook 'delete-frame-functions #'exwm-manage--remove-frame)
   (xcb:+event exwm--connection 'xcb:ConfigureRequest
@@ -714,6 +728,7 @@ border-width: %d; sibling: #x%x; stack-mode: %d"
 
 (defun exwm-manage--exit ()
   "Exit the manage module."
+  (exwm--log)
   (dolist (pair exwm--id-buffer-alist)
     (exwm-manage--unmanage-window (car pair) 'quit))
   (remove-hook 'after-make-frame-functions #'exwm-manage--add-frame)