diff options
-rw-r--r-- | exwm-core.el | 25 | ||||
-rw-r--r-- | exwm-debug.el | 113 | ||||
-rw-r--r-- | exwm-input.el | 32 | ||||
-rw-r--r-- | exwm-layout.el | 14 | ||||
-rw-r--r-- | exwm-manage.el | 16 | ||||
-rw-r--r-- | exwm-systemtray.el | 37 | ||||
-rw-r--r-- | exwm-workspace.el | 7 | ||||
-rw-r--r-- | exwm.el | 14 |
8 files changed, 229 insertions, 29 deletions
diff --git a/exwm-core.el b/exwm-core.el index ab5159c6a7a4..8d5e6dd6911f 100644 --- a/exwm-core.el +++ b/exwm-core.el @@ -31,9 +31,7 @@ (require 'xcb) (require 'xcb-icccm) (require 'xcb-ewmh) - -(eval-and-compile - (defvar exwm-debug-on nil "Non-nil to turn on debug for EXWM.")) +(require 'exwm-debug) (defvar exwm--connection nil "X connection.") @@ -70,10 +68,18 @@ (declare-function exwm-workspace-move-window "exwm-workspace.el" (frame-or-index &optional id)) -(defmacro exwm--log (format-string &rest args) - "Print debug message." +(defmacro exwm--log (&optional format-string &rest objects) + "Emit a message prepending the name of the function being executed. + +FORMAT-STRING is a string specifying the message to output, as in +`format'. The OBJECTS arguments specify the substitutions." (when exwm-debug-on - `(message (concat "[EXWM] " ,format-string) ,@args))) + (unless format-string (setq format-string "")) + `(progn + (exwm-debug--message (concat "%s:\t" ,format-string "\n") + (exwm-debug--compile-time-function-name) + ,@objects) + nil))) (defmacro exwm--debug (&rest forms) (when exwm-debug-on `(progn ,@forms))) @@ -88,6 +94,7 @@ (defun exwm--lock (&rest _args) "Lock (disable all events)." + (exwm--log) (xcb:+request exwm--connection (make-instance 'xcb:ChangeWindowAttributes :window exwm--root @@ -97,6 +104,7 @@ (defun exwm--unlock (&rest _args) "Unlock (enable all events)." + (exwm--log) (xcb:+request exwm--connection (make-instance 'xcb:ChangeWindowAttributes :window exwm--root @@ -281,6 +289,11 @@ least SECS seconds later." (/= ,i exwm-workspace-current-index)]) (number-sequence 0 (1- (exwm-workspace--count)))))))) +(exwm--debug + (let ((map exwm-mode-map)) + (define-key map "\C-c\C-l" #'exwm-debug-clear) + (define-key map "\C-c\C-m" #'exwm-debug-mark))) + (define-derived-mode exwm-mode nil "EXWM" "Major mode for managing X windows. diff --git a/exwm-debug.el b/exwm-debug.el new file mode 100644 index 000000000000..4d1ca7b403eb --- /dev/null +++ b/exwm-debug.el @@ -0,0 +1,113 @@ +;;; exwm-debug.el --- Debugging helpers for EXWM -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; Author: Adrián Medraño Calvo <adrian@medranocalvo.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This module collects functions that help in debugging EXWM. + +;;; Code: + +(eval-and-compile + (defvar exwm-debug-on nil "Non-nil to turn on debug for EXWM.")) + +(defvar exwm-debug-buffer "*EXWM-DEBUG*" "Buffer to write debug messages to.") + +(defvar exwm-debug-backtrace-start-frame 5 + "From which frame to start collecting backtraces.") + +(defun exwm-debug--call-stack () + "Return the current call stack frames." + (let (frames frame + ;; No need to acount for our setq, while, let, ... + (index exwm-debug-backtrace-start-frame)) + (while (setq frame (backtrace-frame index)) + (push frame frames) + (cl-incf index)) + (cl-remove-if-not 'car frames))) + +(defmacro exwm-debug--compile-time-function-name () + "Get the name of outermost definition at expansion time." + (let* ((frame (cl-find-if + (lambda (frame) + (ignore-errors + (let ((clause (car (cl-third frame)))) + (or (equal clause 'defalias) + (equal clause 'cl-defmethod))))) + (reverse (exwm-debug--call-stack)))) + (defn (cl-third frame)) + (deftype (car defn))) + (cl-case deftype + ((defalias) (symbol-name (cl-cadadr defn))) + ((cl-defmethod) (symbol-name (cadr defn))) + (t "<unknown function>")))) + +(defmacro exwm-debug--with-debug-buffer (&rest forms) + "Evaluate FORMS making sure `exwm-debug-buffer' is correctly updated." + `(with-current-buffer (get-buffer-create exwm-debug-buffer) + (let (windows-eob) + ;; Note windows whose point is at EOB. + (dolist (w (get-buffer-window-list exwm-debug-buffer t t)) + (when (= (window-point w) (point-max)) + (push w windows-eob))) + (save-excursion + (goto-char (point-max)) + ,@forms) + ;; Restore point. + (dolist (w windows-eob) + (set-window-point w (point-max)))))) + +(defun exwm-debug--message (format-string &rest objects) + "Print a message to `exwm-debug-buffer'. + +The FORMAT-STRING argument follows the speficies how to print each of +the passed OBJECTS. See `format' for details." + (exwm-debug--with-debug-buffer + (insert (apply #'format format-string objects)))) + +(defmacro exwm-debug--backtrace () + "Print a backtrace to the `exwm-debug-buffer'." + '(exwm-debug--with-debug-buffer + (let ((standard-output exwm-debug-buffer)) + (backtrace)))) + +(defmacro exwm-debug--backtrace-on-error (&rest forms) + "Evaluate FORMS. Printing a backtrace if an error is signaled." + `(let ((debug-on-error t) + (debugger (lambda (&rest _) (exwm-debug--backtrace)))) + ,@forms)) + +(defun exwm-debug-clear () + "Clear the debug buffer." + (interactive) + (exwm-debug--with-debug-buffer + (erase-buffer))) + +(defun exwm-debug-mark () + "Insert a mark in the debug buffer." + (interactive) + (exwm-debug--with-debug-buffer + (insert "\n"))) + + + +(provide 'exwm-debug) + +;;; exwm-debug.el ends here diff --git a/exwm-input.el b/exwm-input.el index 57a28735031c..57fed2d4b88e 100644 --- a/exwm-input.el +++ b/exwm-input.el @@ -157,6 +157,7 @@ This value should always be overwritten.") (defun exwm-input--set-focus (id) "Set input focus to window ID in a proper way." (when (exwm--id->buffer id) + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (exwm-input--update-timestamp (lambda (timestamp id send-input-focus wm-take-focus) @@ -187,6 +188,7 @@ This value should always be overwritten.") ARGS are additional arguments to CALLBACK." (setq exwm-input--timestamp-callback (cons callback args)) + (exwm--log) (xcb:+request exwm--connection (make-instance 'xcb:ChangeProperty :mode xcb:PropMode:Replace @@ -200,6 +202,7 @@ ARGS are additional arguments to CALLBACK." (defun exwm-input--on-PropertyNotify (data _synthetic) "Handle PropertyNotify events." + (exwm--log) (when exwm-input--timestamp-callback (let ((obj (make-instance 'xcb:PropertyNotify))) (xcb:unmarshal obj data) @@ -218,6 +221,7 @@ ARGS are additional arguments to CALLBACK." (with-slots (time root event root-x root-y event-x event-y state) evt (setq buffer (exwm--id->buffer event) window (get-buffer-window buffer t)) + (exwm--log "EnterNotify: buffer=%s; window=%s" buffer window) (when (and buffer window (not (eq window (selected-window)))) (setq frame (window-frame window) frame-xid (frame-parameter frame 'exwm-id)) @@ -265,6 +269,8 @@ ARGS are additional arguments to CALLBACK." (eq (current-buffer) (window-buffer)) (not (string-prefix-p " *temp*" (buffer-name (car (last (buffer-list))))))) + (exwm--log "current-buffer=%S selected-window=%S" + (current-buffer) (selected-window)) (redirect-frame-focus (selected-frame) nil) (setq exwm-input--update-focus-window (selected-window)) (exwm-input--update-focus-defer))) @@ -296,6 +302,7 @@ ARGS are additional arguments to CALLBACK." (defun exwm-input--update-focus (window) "Update input focus." (when (window-live-p window) + (exwm--log "focus-window=%s focus-buffer=%s" window (window-buffer window)) (with-current-buffer (window-buffer window) (if (derived-mode-p 'exwm-mode) (if (not (eq exwm--frame exwm-workspace--current)) @@ -331,6 +338,10 @@ ARGS are additional arguments to CALLBACK." ;; The focus is on another workspace (e.g. it got clicked) ;; so switch to it. (progn + (exwm--log "Switching to %s's workspace %s (%s)" + window + (window-frame window) + (selected-frame)) (set-frame-parameter (selected-frame) 'exwm-selected-window window) (exwm--defer 0 #'exwm-workspace-switch (selected-frame))) @@ -346,12 +357,14 @@ ARGS are additional arguments to CALLBACK." (defun exwm-input--on-minibuffer-setup () "Run in `minibuffer-setup-hook' to set input focus." + (exwm--log) (unless (exwm-workspace--client-p) ;; Set input focus on the Emacs frame (x-focus-frame (window-frame (minibuffer-selected-window))))) (defun exwm-input--set-active-window (&optional id) "Set _NET_ACTIVE_WINDOW." + (exwm--log) (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_ACTIVE_WINDOW :window exwm--root @@ -363,6 +376,8 @@ ARGS are additional arguments to CALLBACK." (mode xcb:Allow:SyncPointer) button-event window buffer frame) (xcb:unmarshal obj data) + (exwm--log "major-mode=%s buffer=%s" + major-mode (buffer-name (current-buffer))) (with-slots (detail time event state) obj (setq button-event (xcb:keysyms:keysym->event exwm--connection detail state) @@ -412,12 +427,15 @@ ARGS are additional arguments to CALLBACK." "Handle KeyPress event." (let ((obj (make-instance 'xcb:KeyPress))) (xcb:unmarshal obj data) + (exwm--log "major-mode=%s buffer=%s" + major-mode (buffer-name (current-buffer))) (if (derived-mode-p 'exwm-mode) (funcall exwm--on-KeyPress obj data) (exwm-input--on-KeyPress-char-mode obj)))) (defun exwm-input--on-CreateNotify (data _synthetic) "Handle CreateNotify events." + (exwm--log) (let ((evt (make-instance 'xcb:CreateNotify))) (xcb:unmarshal evt data) (with-slots (window) evt @@ -425,6 +443,7 @@ ARGS are additional arguments to CALLBACK." (defun exwm-input--update-global-prefix-keys () "Update `exwm-input--global-prefix-keys'." + (exwm--log) (when exwm--connection (let ((original exwm-input--global-prefix-keys)) (setq exwm-input--global-prefix-keys nil) @@ -438,6 +457,7 @@ ARGS are additional arguments to CALLBACK." 'children)))))) (defun exwm-input--grab-global-prefix-keys (&rest xwins) + (exwm--log) (let ((req (make-instance 'xcb:GrabKey :owner-events 0 :grab-window nil @@ -450,6 +470,8 @@ ARGS are additional arguments to CALLBACK." (setq keysym (xcb:keysyms:event->keysym exwm--connection k) keycode (xcb:keysyms:keysym->keycode exwm--connection (car keysym))) + (exwm--log "Grabbing key=%s (keysym=%s keycode=%s)" + (single-key-description k) keysym keycode) (setf (slot-value req 'modifiers) (cdr keysym) (slot-value req 'key) keycode) (dolist (xwin xwins) @@ -498,6 +520,7 @@ specifically saved in the Customize interface for `exwm-input-global-keys'. In configuration you should customize or set `exwm-input-global-keys' instead." (interactive "KSet key globally: \nCSet key %s to command: ") + (exwm--log) (setq exwm-input-global-keys (append exwm-input-global-keys (list (cons key command)))) (exwm-input--set-key key command) @@ -517,6 +540,7 @@ instead." (defun exwm-input--mimic-read-event (event) "Process EVENT as if it were returned by `read-event'." + (exwm--log) (unless (eq 0 extra-keyboard-modifiers) (setq event (event-convert-list (append (event-modifiers extra-keyboard-modifiers) @@ -559,6 +583,7 @@ instead." (with-slots (detail state) key-press (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state)) event raw-event mode) + (exwm--log "%s" keysym) (when (and (/= 0 (car keysym)) (setq raw-event (xcb:keysyms:keysym->event exwm--connection (car keysym) @@ -610,6 +635,7 @@ instead." (with-slots (detail state) key-press (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state)) event raw-event) + (exwm--log "%s" keysym) (when (and (/= 0 (car keysym)) (setq raw-event (xcb:keysyms:keysym->event exwm--connection (car keysym) @@ -660,6 +686,7 @@ instead." "Grab all key events on window ID." (unless id (setq id (exwm--buffer->id (window-buffer)))) (when id + (exwm--log "id=#x%x" id) (when (xcb:+request-checked+request-check exwm--connection (make-instance 'xcb:GrabKey :owner-events 0 @@ -676,6 +703,7 @@ instead." "Ungrab all key events on window ID." (unless id (setq id (exwm--buffer->id (window-buffer)))) (when id + (exwm--log "id=#x%x" id) (when (xcb:+request-checked+request-check exwm--connection (make-instance 'xcb:UngrabKey :key xcb:Grab:Any @@ -692,6 +720,7 @@ instead." (interactive (list (when (derived-mode-p 'exwm-mode) (exwm--buffer->id (window-buffer))))) (when id + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (exwm-input--grab-keyboard id) (setq exwm--keyboard-grabbed t) @@ -704,6 +733,7 @@ instead." (interactive (list (when (derived-mode-p 'exwm-mode) (exwm--buffer->id (window-buffer))))) (when id + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (exwm-input--release-keyboard id) (setq exwm--keyboard-grabbed nil) @@ -716,6 +746,7 @@ instead." (interactive (list (when (derived-mode-p 'exwm-mode) (exwm--buffer->id (window-buffer))))) (when id + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (if exwm--keyboard-grabbed (exwm-input-release-keyboard id) @@ -731,6 +762,7 @@ instead." (car keysym))) (when (/= 0 keycode) (setq id (exwm--buffer->id (window-buffer (selected-window)))) + (exwm--log "id=#x%x event=%s keycode" id event keycode) (dolist (class '(xcb:KeyPress xcb:KeyRelease)) (xcb:+request exwm--connection (make-instance 'xcb:SendEvent diff --git a/exwm-layout.el b/exwm-layout.el index 98a27d0ca03f..09a34985a7c6 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -59,6 +59,7 @@ (defun exwm-layout--set-state (id state) "Set WM_STATE." + (exwm--log "id=#x%x" id) (xcb:+request exwm--connection (make-instance 'xcb:icccm:set-WM_STATE :window id :state state :icon xcb:Window:None)) @@ -146,6 +147,7 @@ (cl-defun exwm-layout-set-fullscreen (&optional id) "Make window ID fullscreen." (interactive) + (exwm--log "id=#x%x" (or id 0)) (unless (and (or id (derived-mode-p 'exwm-mode)) (not (exwm-layout--fullscreen-p))) (cl-return-from exwm-layout-set-fullscreen)) @@ -174,6 +176,7 @@ (cl-defun exwm-layout-unset-fullscreen (&optional id) "Restore window from fullscreen state." (interactive) + (exwm--log "id=#x%x" (or id 0)) (unless (and (or id (derived-mode-p 'exwm-mode)) (exwm-layout--fullscreen-p)) (cl-return-from exwm-layout-unset-fullscreen)) @@ -203,6 +206,7 @@ (cl-defun exwm-layout-toggle-fullscreen (&optional id) "Toggle fullscreen mode." (interactive (list (exwm--buffer->id (window-buffer)))) + (exwm--log "id=#x%x" (or id 0)) (unless (or id (derived-mode-p 'exwm-mode)) (cl-return-from exwm-layout-toggle-fullscreen)) (when id @@ -234,6 +238,7 @@ selected by `other-buffer'." (defun exwm-layout--set-client-list-stacking () "Set _NET_CLIENT_LIST_STACKING." + (exwm--log) (let (id clients-floating clients clients-iconic clients-other) (dolist (pair exwm--id-buffer-alist) (setq id (car pair)) @@ -261,6 +266,7 @@ selected by `other-buffer'." ;; `window-configuration-change-hook' makes the frame selected. (unless frame (setq frame (selected-frame))) + (exwm--log "frame=%s" frame) (if (not (exwm-workspace--workspace-p frame)) (if (frame-parameter frame 'exwm-outer-id) (exwm-layout--refresh-floating frame) @@ -352,6 +358,7 @@ selected by `other-buffer'." (defun exwm-layout--on-minibuffer-setup () "Refresh layout when minibuffer grows." + (exwm--log) (unless (exwm-workspace--client-p) (exwm--defer 0 (lambda () (when (< 1 (window-height (minibuffer-window))) @@ -364,6 +371,7 @@ selected by `other-buffer'." (or (cl-position ?\n (current-message)) (> (length (current-message)) (frame-width exwm-workspace--current)))) + (exwm--log) (if dirty (exwm-layout--refresh) (exwm--defer 0 #'exwm-layout--refresh)))) @@ -380,6 +388,7 @@ Normal hints are checked and regarded if the selected window is displaying an `exwm-mode' buffer. However, this may violate the normal hints set on other X windows." (interactive "p") + (exwm--log) (cond ((zerop delta)) ;no operation ((window-minibuffer-p)) ;avoid resize minibuffer-window @@ -485,6 +494,7 @@ See also `exwm-layout-enlarge-window'." (defun exwm-layout-hide-mode-line () "Hide mode-line." (interactive) + (exwm--log) (when (and (derived-mode-p 'exwm-mode) mode-line-format) (let (mode-line-height) (when exwm--floating-frame @@ -503,6 +513,7 @@ See also `exwm-layout-enlarge-window'." (defun exwm-layout-show-mode-line () "Show mode-line." (interactive) + (exwm--log) (when (and (derived-mode-p 'exwm-mode) (not mode-line-format)) (setq mode-line-format exwm--mode-line-format exwm--mode-line-format nil) @@ -520,6 +531,7 @@ See also `exwm-layout-enlarge-window'." (defun exwm-layout-toggle-mode-line () "Toggle the display of mode-line." (interactive) + (exwm--log) (when (derived-mode-p 'exwm-mode) (if mode-line-format (exwm-layout-hide-mode-line) @@ -528,6 +540,7 @@ See also `exwm-layout-enlarge-window'." (defun exwm-layout--init () "Initialize layout module." ;; Auto refresh layout + (exwm--log) (add-hook 'window-configuration-change-hook #'exwm-layout--refresh) ;; The behavior of `window-configuration-change-hook' will be changed. (when (fboundp 'window-pixel-width-before-size-change) @@ -541,6 +554,7 @@ See also `exwm-layout-enlarge-window'." (defun exwm-layout--exit () "Exit the layout module." + (exwm--log) (remove-hook 'window-configuration-change-hook #'exwm-layout--refresh) (when (fboundp 'window-pixel-width-before-size-change) (remove-hook 'window-size-change-functions #'exwm-layout--refresh)) diff --git a/exwm-manage.el b/exwm-manage.el index 349157f1ff20..81a486c09795 100644 --- a/exwm-manage.el +++ b/exwm-manage.el @@ -119,6 +119,7 @@ You can still make the X windows floating afterwards." (defun exwm-manage--update-geometry (id &optional force) "Update window geometry." + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (unless (and exwm--geometry (not force)) (let ((reply (xcb:+request-unchecked+reply exwm--connection @@ -134,6 +135,7 @@ You can still make the X windows floating afterwards." (defun exwm-manage--update-ewmh-state (id) "Update _NET_WM_STATE." + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (unless exwm--ewmh-state (let ((reply (xcb:+request-unchecked+reply exwm--connection @@ -144,6 +146,7 @@ You can still make the X windows floating afterwards." (defun exwm-manage--update-mwm-hints (id &optional force) "Update _MOTIF_WM_HINTS." + (exwm--log "id=#x%x" id) (with-current-buffer (exwm--id->buffer id) (unless (and (not exwm--mwm-hints-decorations) (not force)) (let ((reply (xcb:+request-unchecked+reply exwm--connection @@ -167,6 +170,7 @@ You can still make the X windows floating afterwards." (defun exwm-manage--set-client-list () "Set _NET_CLIENT_LIST." + (exwm--log) (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST :window exwm--root @@ -174,6 +178,7 @@ You can still make the X windows floating afterwards." (cl-defun exwm-manage--get-configurations () "Retrieve configurations for this buffer." + (exwm--log) (when (derived-mode-p 'exwm-mode) (dolist (i exwm-manage-configurations) (save-current-buffer @@ -412,6 +417,7 @@ manager is shutting down." (defun exwm-manage--scan () "Search for existing windows and try to manage them." + (exwm--log) (let* ((tree (xcb:+request-unchecked+reply exwm--connection (make-instance 'xcb:QueryTree :window exwm--root))) @@ -433,6 +439,7 @@ manager is shutting down." (defun exwm-manage--kill-buffer-query-function () "Run in `kill-buffer-query-functions'." + (exwm--log "id=#x%x; buffer=%s" exwm--id (current-buffer)) (catch 'return (when (or (not exwm--id) (xcb:+request-checked+request-check exwm--connection @@ -510,6 +517,7 @@ Would you like to kill it? " (defun exwm-manage--kill-client (&optional id) "Kill an X client." (unless id (setq id (exwm--buffer->id (current-buffer)))) + (exwm--log "id=#x%x" id) (let* ((response (xcb:+request-unchecked+reply exwm--connection (make-instance 'xcb:ewmh:get-_NET_WM_PID :window id))) (pid (and response (slot-value response 'value))) @@ -526,12 +534,14 @@ Would you like to kill it? " (defun exwm-manage--add-frame (frame) "Run in `after-make-frame-functions'." + (exwm--log "frame=%s" frame) (when (display-graphic-p frame) (push (string-to-number (frame-parameter frame 'outer-window-id)) exwm-manage--frame-outer-id-list))) (defun exwm-manage--remove-frame (frame) "Run in `delete-frame-functions'." + (exwm--log "frame=%s" frame) (when (display-graphic-p frame) (setq exwm-manage--frame-outer-id-list (delq (string-to-number (frame-parameter frame 'outer-window-id)) @@ -539,6 +549,7 @@ Would you like to kill it? " (defun exwm-manage--on-ConfigureRequest (data _synthetic) "Handle ConfigureRequest event." + (exwm--log) (let ((obj (make-instance 'xcb:ConfigureRequest)) buffer edges width-delta height-delta) (xcb:unmarshal obj data) @@ -631,6 +642,7 @@ border-width: %d; sibling: #x%x; stack-mode: %d" (let ((obj (make-instance 'xcb:MapRequest))) (xcb:unmarshal obj data) (with-slots (parent window) obj + (exwm--log "id=#x%x parent=#x%x" window parent) (if (assoc window exwm--id-buffer-alist) (with-current-buffer (exwm--id->buffer window) (if (exwm-layout--iconic-state-p) @@ -650,12 +662,13 @@ border-width: %d; sibling: #x%x; stack-mode: %d" (let ((obj (make-instance 'xcb:UnmapNotify))) (xcb:unmarshal obj data) (with-slots (window) obj - (exwm--log "UnmapNotify from #x%x" window) + (exwm--log "id=#x%x" window) (exwm-manage--unmanage-window window t)))) (defun exwm-manage--on-DestroyNotify (data synthetic) "Handle DestroyNotify event." (unless synthetic + (exwm--log) (let ((obj (make-instance 'xcb:DestroyNotify))) (xcb:unmarshal obj data) (exwm--log "DestroyNotify from #x%x" (slot-value obj 'window)) @@ -664,6 +677,7 @@ border-width: %d; sibling: #x%x; stack-mode: %d" (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 diff --git a/exwm-systemtray.el b/exwm-systemtray.el index ba1e3889347a..d3244ab8d088 100644 --- a/exwm-systemtray.el +++ b/exwm-systemtray.el @@ -70,7 +70,7 @@ You shall use the default value if using auto-hide minibuffer." (defvar exwm-systemtray--connection nil "The X connection.") -(defvar exwm-systemtray--embedder nil "The embedder window.") +(defvar exwm-systemtray--embedder-window nil "The embedder window.") (defvar exwm-systemtray--list nil "The icon list.") @@ -112,7 +112,7 @@ You shall use the default value if using auto-hide minibuffer." (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ReparentWindow :window icon - :parent exwm-systemtray--embedder + :parent exwm-systemtray--embedder-window :x 0 ;; Vertically centered. :y (/ (- exwm-systemtray-height height*) 2))) @@ -162,7 +162,8 @@ You shall use the default value if using auto-hide minibuffer." (make-instance 'xcb:xembed:EMBEDDED-NOTIFY :window icon :time xcb:Time:CurrentTime - :embedder exwm-systemtray--embedder + :embedder + exwm-systemtray--embedder-window :version 0) exwm-systemtray--connection))) (push `(,icon . ,(make-instance 'exwm-systemtray--icon @@ -190,7 +191,8 @@ You shall use the default value if using auto-hide minibuffer." "Refresh the system tray." ;; Make sure to redraw the embedder. (xcb:+request exwm-systemtray--connection - (make-instance 'xcb:UnmapWindow :window exwm-systemtray--embedder)) + (make-instance 'xcb:UnmapWindow + :window exwm-systemtray--embedder-window)) (let ((x exwm-systemtray-icon-gap) map) (dolist (pair exwm-systemtray--list) @@ -207,14 +209,15 @@ You shall use the default value if using auto-hide minibuffer." exwm-workspace-current-index))) (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ConfigureWindow - :window exwm-systemtray--embedder + :window exwm-systemtray--embedder-window :value-mask (logior xcb:ConfigWindow:X xcb:ConfigWindow:Width) :x (- (aref workarea 2) x) :width x))) (when map (xcb:+request exwm-systemtray--connection - (make-instance 'xcb:MapWindow :window exwm-systemtray--embedder)))) + (make-instance 'xcb:MapWindow + :window exwm-systemtray--embedder-window)))) (xcb:flush exwm-systemtray--connection)) (defun exwm-systemtray--on-DestroyNotify (data _synthetic) @@ -230,7 +233,7 @@ You shall use the default value if using auto-hide minibuffer." (let ((obj (make-instance 'xcb:ReparentNotify))) (xcb:unmarshal obj data) (with-slots (window parent) obj - (when (and (/= parent exwm-systemtray--embedder) + (when (and (/= parent exwm-systemtray--embedder-window) (assoc window exwm-systemtray--list)) (exwm-systemtray--unembed window))))) @@ -325,7 +328,7 @@ You shall use the default value if using auto-hide minibuffer." (unless (exwm-workspace--minibuffer-own-frame-p) (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ReparentWindow - :window exwm-systemtray--embedder + :window exwm-systemtray--embedder-window :parent (string-to-number (frame-parameter exwm-workspace--current 'window-id)) @@ -339,7 +342,7 @@ You shall use the default value if using auto-hide minibuffer." (unless (exwm-workspace--minibuffer-own-frame-p) (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ConfigureWindow - :window exwm-systemtray--embedder + :window exwm-systemtray--embedder-window :value-mask xcb:ConfigWindow:Y :y (- (frame-pixel-height exwm-workspace--current) exwm-systemtray-height)))) @@ -353,7 +356,7 @@ You shall use the default value if using auto-hide minibuffer." (cl-assert (not exwm-systemtray--connection)) (cl-assert (not exwm-systemtray--list)) (cl-assert (not exwm-systemtray--selection-owner-window)) - (cl-assert (not exwm-systemtray--embedder)) + (cl-assert (not exwm-systemtray--embedder-window)) (unless exwm-systemtray-height (setq exwm-systemtray-height (max exwm-systemtray--icon-min-size (line-pixel-height)))) @@ -414,7 +417,8 @@ You shall use the default value if using auto-hide minibuffer." ;; Set _NET_WM_NAME. (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ewmh:set-_NET_WM_NAME - :window id :data "EXWM system tray selection owner")) + :window id + :data "EXWM: exwm-systemtray--selection-owner-window")) ;; Set the _NET_SYSTEM_TRAY_ORIENTATION property. (xcb:+request exwm-systemtray--connection (make-instance 'xcb:xembed:set-_NET_SYSTEM_TRAY_ORIENTATION @@ -423,7 +427,7 @@ You shall use the default value if using auto-hide minibuffer." ;; Create the embedder. (let ((id (xcb:generate-id exwm-systemtray--connection)) frame parent depth y) - (setq exwm-systemtray--embedder id) + (setq exwm-systemtray--embedder-window id) (if (exwm-workspace--minibuffer-own-frame-p) (setq frame exwm-workspace--minibuffer y (if (>= (line-pixel-height) exwm-systemtray-height) @@ -460,7 +464,8 @@ You shall use the default value if using auto-hide minibuffer." ;; Set _NET_WM_NAME. (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ewmh:set-_NET_WM_NAME - :window id :data "EXWM system tray embedder"))) + :window id + :data "EXWM: exwm-systemtray--embedder-window"))) (xcb:flush exwm-systemtray--connection) ;; Attach event listeners. (xcb:+event exwm-systemtray--connection 'xcb:DestroyNotify @@ -494,10 +499,10 @@ You shall use the default value if using auto-hide minibuffer." ;; parent of the embedder). (xcb:+request exwm-systemtray--connection (make-instance 'xcb:UnmapWindow - :window exwm-systemtray--embedder)) + :window exwm-systemtray--embedder-window)) (xcb:+request exwm-systemtray--connection (make-instance 'xcb:ReparentWindow - :window exwm-systemtray--embedder + :window exwm-systemtray--embedder-window :parent exwm--root :x 0 :y 0)) @@ -505,7 +510,7 @@ You shall use the default value if using auto-hide minibuffer." (setq exwm-systemtray--connection nil exwm-systemtray--list nil exwm-systemtray--selection-owner-window nil - exwm-systemtray--embedder nil) + exwm-systemtray--embedder-window nil) (remove-hook 'exwm-workspace-switch-hook #'exwm-systemtray--on-workspace-switch) (remove-hook 'exwm-workspace--update-workareas-hook diff --git a/exwm-workspace.el b/exwm-workspace.el index 1034966374bf..bcfffff1d354 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -375,6 +375,7 @@ NIL if FRAME is not a workspace" (defun exwm-workspace--set-active (frame active) "Make frame FRAME active on its output." + (exwm--log "active=%s; frame=%s" frame active) (set-frame-parameter frame 'exwm-active active) (if active (exwm-workspace--set-fullscreen frame) @@ -387,6 +388,7 @@ NIL if FRAME is not a workspace" (defun exwm-workspace--set-fullscreen (frame) "Make frame FRAME fullscreen according to `exwm-workspace--workareas'." + (exwm--log "frame=%s" frame) (let ((workarea (elt exwm-workspace--workareas (exwm-workspace--position frame))) (id (frame-parameter frame 'exwm-outer-id)) @@ -396,6 +398,7 @@ NIL if FRAME is not a workspace" y (aref workarea 1) width (aref workarea 2) height (aref workarea 3)) + (exwm--log "x=%s; y=%s; w=%s; h=%s" x y width height) (when (and (eq frame exwm-workspace--current) (exwm-workspace--minibuffer-own-frame-p)) (exwm-workspace--resize-minibuffer-frame)) @@ -516,6 +519,7 @@ for internal use only." (<= 0 current-prefix-arg (exwm-workspace--count))) current-prefix-arg) (t 0)))) + (exwm--log) (let* ((frame (exwm-workspace--workspace-from-frame-or-index frame-or-index)) (old-frame exwm-workspace--current) (index (exwm-workspace--position frame)) @@ -665,6 +669,7 @@ Passing a workspace frame as the first option is for internal use only." (format "Swap workspace %d with: " (exwm-workspace--position w1)))) (list w1 w2)))) + (exwm--log) (let ((pos1 (exwm-workspace--position workspace1)) (pos2 (exwm-workspace--position workspace2))) (if (or (not pos1) (not pos2) (= pos1 pos2)) @@ -703,6 +708,7 @@ before it." (<= 0 current-prefix-arg (exwm-workspace--count))) (list exwm-workspace--current current-prefix-arg)) (t (list exwm-workspace--current 0)))) + (exwm--log) (let ((pos (exwm-workspace--position workspace)) flag start end index) (if (= nth pos) @@ -928,6 +934,7 @@ INDEX must not exceed the current number of workspaces." (remq #'exwm-input--on-buffer-list-update buffer-list-update-hook))) (rename-buffer (concat " " (buffer-name))))))))))) + (exwm--log) (when buffer-or-name (with-current-buffer buffer-or-name (if (derived-mode-p 'exwm-mode) diff --git a/exwm.el b/exwm.el index 9f9b6f468105..b9c1d0ba3475 100644 --- a/exwm.el +++ b/exwm.el @@ -360,6 +360,7 @@ (xcb:unmarshal obj data) (setq id (slot-value obj 'window) atom (slot-value obj 'atom)) + (exwm--log "atom=%s(%s)" (x-get-atom-name atom exwm-workspace--current) atom) (setq buffer (exwm--id->buffer id)) (if (not (buffer-live-p buffer)) ;; Properties of unmanaged X windows. @@ -397,6 +398,7 @@ (setq type (slot-value obj 'type) id (slot-value obj 'window) data (slot-value (slot-value obj 'data) 'data32)) + (exwm--log "atom=%s(%s)" (x-get-atom-name type exwm-workspace--current) type) (cond ;; _NET_NUMBER_OF_DESKTOPS. ((= type xcb:Atom:_NET_NUMBER_OF_DESKTOPS) @@ -665,15 +667,15 @@ :visual 0 :value-mask xcb:CW:OverrideRedirect :override-redirect 1)) + ;; Set _NET_WM_NAME + (xcb:+request exwm--connection + (make-instance 'xcb:ewmh:set-_NET_WM_NAME + :window new-id :data "EXWM: exwm--guide-window")) (dolist (i (list exwm--root new-id)) ;; Set _NET_SUPPORTING_WM_CHECK (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_SUPPORTING_WM_CHECK - :window i :data new-id)) - ;; Set _NET_WM_NAME - (xcb:+request exwm--connection - (make-instance 'xcb:ewmh:set-_NET_WM_NAME - :window i :data "EXWM")))) + :window i :data new-id)))) ;; Set _NET_DESKTOP_VIEWPORT (we don't support large desktop). (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_DESKTOP_VIEWPORT @@ -712,7 +714,7 @@ manager. If t, replace it, if nil, abort and ask the user if `ask'." :override-redirect 0)) (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_WM_NAME - :window new-owner :data "EXWM selection owner")) + :window new-owner :data "EXWM: exwm--wmsn-window")) (xcb:+request-checked+request-check exwm--connection (make-instance 'xcb:SetSelectionOwner :selection xcb:Atom:WM_S0 |