emacs-exwm / exwm

Emacs X Window Manager
https://elpa.gnu.org/packages/exwm.html
GNU General Public License v3.0
236 stars 10 forks source link

Function exwm-layout-unset-fullscreen cannot be used to unset a non-selected window #25

Open ceefrench opened 7 months ago

ceefrench commented 7 months ago

I have a use-case for wanting to ensure that a given window is not in fullscreen mode before running some code on it, and was hoping it would be as easy as getting the X window id and feeding it to exwm-layout-unset-fullscreen before running my code. However, the function exits early in this block of code:

(unless (and (or id (derived-mode-p 'exwm-mode))
               (exwm-layout--fullscreen-p))
    (cl-return-from exwm-layout-unset-fullscreen))

The second line, as far as I can tell, checks to see that specifically the current window is fullscreen, however this may not be the case when supplying an x-id to the function. Removing the line allows for the functionality I was looking for, however, I'm not sure if it introduces any unintended behaviour, so maybe another solution may be more preferable. I'm curious about whether the condition in the second line is actually necessary. My assumption would be that running the rest of the code on a window which is not in fullscreen mode would simply have no effect, but I could easily be wrong about that.

ceefrench commented 7 months ago

After testing out my change some more, I see some problems with it, where similarly to before, the function get-buffer-window is given a nil argument for BUFFER-OR-NAME resulting in it acting on the current window. I made some changes and now the function looks like the following, and seems to work:

(cl-defun exwm-layout-unset-fullscreen (&optional id)
  "Restore X window ID from fullscreen state."
  (interactive)
  (exwm--log "id=#x%x" (or id 0))
  (unless (or id (derived-mode-p 'exwm-mode))
    (cl-return-from exwm-layout-unset-fullscreen))
  (let ((buf (exwm--id->buffer id)))
       (with-current-buffer (if id (exwm--id->buffer id) (window-buffer))
         ;; `exwm-layout--show' relies on `exwm--ewmh-state' to decide whether to
         ;; fullscreen the window.
         (setq exwm--ewmh-state
               (delq xcb:Atom:_NET_WM_STATE_FULLSCREEN exwm--ewmh-state))
         (exwm-layout--set-ewmh-state exwm--id)
         (if exwm--floating-frame
             (exwm-layout--show exwm--id (frame-root-window exwm--floating-frame))
           (xcb:+request exwm--connection
               (make-instance 'xcb:ConfigureWindow
                              :window exwm--id
                              :value-mask (logior xcb:ConfigWindow:Sibling
                                                  xcb:ConfigWindow:StackMode)
                              :sibling exwm--guide-window
                              :stack-mode xcb:StackMode:Above))
           (let ((window (get-buffer-window buf t)))
             (when window
               (exwm-layout--show exwm--id window))))
         (xcb:flush exwm--connection)
         (set-window-dedicated-p (get-buffer-window buf t) nil)
         (when (eq 'line-mode exwm--selected-input-mode)
           (exwm-input--grab-keyboard exwm--id)))))
Stebalien commented 6 months ago

Yeah, that's a bug.