diff options
Diffstat (limited to 'exwm-manage.el')
-rw-r--r-- | exwm-manage.el | 91 |
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) |