[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/exwm 7f12d9f: Add multi-dock support and fix fullscreen
From: |
Chris Feng |
Subject: |
[elpa] externals/exwm 7f12d9f: Add multi-dock support and fix fullscreen issues with dock |
Date: |
Fri, 15 Jul 2016 12:20:46 +0000 (UTC) |
branch: externals/exwm
commit 7f12d9fc7a88369a479ed2f0489ff3b10b347d13
Author: Chris Feng <address@hidden>
Commit: Chris Feng <address@hidden>
Add multi-dock support and fix fullscreen issues with dock
* exwm.el (exwm--update-strut-legacy, exwm--update-strut-partial)
(exwm--update-strut): Rename (strut => struts).
* exwm-manage.el (exwm-manage--manage-window): Listen for
UnmapNotify/DestroyNotify events of docks to stop tracking them.
(exwm-manage--unmanage-window): Remove dock from tracking list when
it's unmapped/destroyed.
* exwm-workspace.el (exwm-workspace--id-struts-alist): New variable
for tracking docks.
(exwm-workspace--struts): Now it stores merged struts.
(exwm-workspace--update-struts): New function for doing the 'merge'.
* exwm.el (exwm--update-struts-legacy, exwm--update-struts-partial):
Now update struts for multiple docks.
* exwm-layout.el (exwm-layout-set-fullscreen)
(exwm-layout-unset-fullscreen):
* exwm-manage.el (exwm-manage--unmanage-window):
Fix fullscreen mode with dock.
* exwm-workspace.el (exwm-workspace--set-fullscreen): Add optional
arguments for ignoring struts / resizing container only.
(exwm-workspace-switch): Restack workspace/docks appropriately.
---
exwm-layout.el | 25 ++++++++++++-
exwm-manage.el | 29 +++++++++++++--
exwm-randr.el | 3 +-
exwm-workspace.el | 105 ++++++++++++++++++++++++++++++++++++-----------------
exwm.el | 52 ++++++++++++++------------
5 files changed, 149 insertions(+), 65 deletions(-)
diff --git a/exwm-layout.el b/exwm-layout.el
index 259788f..b79e42e 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -155,6 +155,9 @@
(defvar exwm-workspace--current)
(defvar exwm-workspace--list)
+(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el"
+ (frame &optional no-struts container-only))
+
;;;###autoload
(defun exwm-layout-set-fullscreen (&optional id)
"Make window ID fullscreen."
@@ -169,9 +172,25 @@
:drawable exwm--container))))
(setq exwm--floating-frame-position
(vector (slot-value geometry 'x) (slot-value geometry 'y)))))
- (exwm-layout--resize-container exwm--id exwm--container 0 0
+ ;; Expand the workspace frame & its container to fill the whole screen.
+ (exwm-workspace--set-fullscreen exwm--frame t t)
+ ;; Raise the workspace container (in case there are docks).
+ (xcb:+request exwm--connection
+ (make-instance 'xcb:ConfigureWindow
+ :window (frame-parameter exwm--frame 'exwm-workspace)
+ :value-mask xcb:ConfigWindow:StackMode
+ :stack-mode xcb:StackMode:Above))
+ ;; Expand the X window and its container to fill the whole screen.
+ ;; Rationale: Floating X windows may not be positioned at (0, 0)
+ ;; due to the extra border.
+ (exwm-layout--resize-container nil exwm--container 0 0
+ (exwm-workspace--current-width)
+ (exwm-workspace--current-height)
+ t)
+ (exwm-layout--resize-container nil exwm--id 0 0
(exwm-workspace--current-width)
- (exwm-workspace--current-height))
+ (exwm-workspace--current-height)
+ t)
;; Raise the X window.
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
@@ -193,6 +212,8 @@
(with-current-buffer (if id (exwm--id->buffer id) (window-buffer))
(unless exwm--fullscreen
(user-error "Not in full-screen mode."))
+ ;; Restore the size of this workspace.
+ (exwm-workspace--set-fullscreen exwm--frame)
(if exwm--floating-frame
;; Restore the floating frame.
(xcb:+request exwm--connection
diff --git a/exwm-manage.el b/exwm-manage.el
index 1394890..3597822 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -86,7 +86,7 @@ corresponding buffer.")
(declare-function exwm--update-title "exwm.el" (id))
(declare-function exwm--update-hints "exwm.el" (id &optional force))
(declare-function exwm--update-protocols "exwm.el" (id &optional force))
-(declare-function exwm--update-strut "exwm.el" (id))
+(declare-function exwm--update-struts "exwm.el" (id))
(declare-function exwm-floating--set-floating "exwm-floating.el" (id))
(declare-function exwm-floating--unset-floating "exwm-floating.el" (id))
(declare-function exwm-workspace--set-desktop "exwm-workspace.el" (id))
@@ -133,7 +133,7 @@ corresponding buffer.")
(exwm--log "No need to manage #x%x" id)
;; Update struts.
(when (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DOCK exwm-window-type)
- (exwm--update-strut id))
+ (exwm--update-struts id))
;; Remove all events
(xcb:+request exwm--connection
(make-instance 'xcb:ChangeWindowAttributes
@@ -141,8 +141,9 @@ corresponding buffer.")
:event-mask
(if (memq xcb:Atom:_NET_WM_WINDOW_TYPE_DOCK
exwm-window-type)
- ;; Listen for change of struts property of dock.
- xcb:EventMask:PropertyChange
+ ;; Listen for PropertyChange (struts) and
+ ;; UnmapNotify/DestroyNotify event of the dock.
+ exwm--client-event-mask
xcb:EventMask:NoEvent)))
;; The window needs to be mapped
(xcb:+request exwm--connection
@@ -247,6 +248,15 @@ corresponding buffer.")
(with-current-buffer (exwm--id->buffer id)
(run-hooks 'exwm-manage-finish-hook)))))
+(defvar exwm-workspace--id-struts-alist)
+(defvar exwm-workspace--list)
+
+(declare-function exwm-workspace--update-struts "exwm-workspace.el" ())
+(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el"
+ (frame &optional no-struts container-only))
+(declare-function exwm-workspace--set-workareas "exwm-workspace.el"
+ (&optional workareas))
+
(defun exwm-manage--unmanage-window (id &optional withdraw-only)
"Unmanage window ID.
@@ -257,6 +267,14 @@ manager is shutting down."
(exwm--log "Unmanage #x%x (buffer: %s, widthdraw: %s)"
id buffer withdraw-only)
(setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
+ ;; Update workspaces when a dock is destroyed.
+ (when (assq id exwm-workspace--id-struts-alist)
+ (setq exwm-workspace--id-struts-alist
+ (assq-delete-all id exwm-workspace--id-struts-alist))
+ (exwm-workspace--update-struts)
+ (dolist (f exwm-workspace--list)
+ (exwm-workspace--set-fullscreen f))
+ (exwm-workspace--set-workareas))
(when (buffer-live-p buffer)
(with-current-buffer buffer
;; Flickering seems unavoidable here if the DestroyWindow request is
@@ -314,6 +332,9 @@ manager is shutting down."
(xcb:+request exwm--connection
(make-instance 'xcb:ReparentWindow
:window window :parent exwm--root :x 0 :y 0))))
+ ;; Restore the workspace if this X window is currently fullscreen.
+ (when exwm--fullscreen
+ (exwm-workspace--set-fullscreen exwm--frame))
;; Destroy the X window container (and the frame container if any).
(xcb:+request exwm--connection
(make-instance 'xcb:DestroyWindow :window exwm--container))
diff --git a/exwm-randr.el b/exwm-randr.el
index f71120a..9f6be78 100644
--- a/exwm-randr.el
+++ b/exwm-randr.el
@@ -58,7 +58,8 @@
(defvar exwm-workspace-number)
(defvar exwm-workspace--list)
-(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame))
+(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el"
+ (frame &optional no-struts container-only))
(declare-function exwm-workspace--set-workareas "exwm-workspace.el"
(&optional workareas))
(declare-function exwm-workspace--set-desktop-geometry "exwm-workspace.el" ())
diff --git a/exwm-workspace.el b/exwm-workspace.el
index 6902151..cfbe02a 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -128,10 +128,30 @@ Value nil means to use the default position which is
fixed at bottom, while
"Reports whether the minibuffer is displayed in its own frame."
(memq exwm-workspace-minibuffer-position '(top bottom)))
-;; FIXME: RandR and multiple docks.
-(defvar exwm-workspace--strut nil "Areas occupied by struts.")
-(defvar exwm-workspace--strut-is-partial nil
- "Whether the struts are from _NET_WM_STRUT_PARTIAL.")
+(defvar exwm-workspace--id-struts-alist nil "Alist of X window and struts.")
+(defvar exwm-workspace--struts nil "Areas occupied by struts.")
+
+(defun exwm-workspace--update-struts ()
+ "Update `exwm-workspace--struts'."
+ (let ((left 0)
+ (right 0)
+ (top 0)
+ (bottom 0)
+ struts)
+ (dolist (pair exwm-workspace--id-struts-alist)
+ (setq struts (cdr pair))
+ (when struts
+ (when (< left (aref struts 0))
+ (setq left (aref struts 0)))
+ (when (< right (aref struts 1))
+ (setq right (aref struts 1)))
+ (when (< top (aref struts 2))
+ (setq top (aref struts 2)))
+ (when (< bottom (aref struts 3))
+ (setq bottom (aref struts 3)))))
+ (setq exwm-workspace--struts (vector left right top bottom))
+ (when (equal exwm-workspace--struts [0 0 0 0])
+ (setq exwm-workspace--struts nil))))
(defvar exwm-workspace--fullscreen-frame-count 0
"Count the fullscreen workspace frames.")
@@ -139,8 +159,12 @@ Value nil means to use the default position which is fixed
at bottom, while
(declare-function exwm-layout--resize-container "exwm-layout.el"
(id container x y width height &optional container-only))
-(defun exwm-workspace--set-fullscreen (frame)
- "Make frame FRAME fullscreen, with regard to its RandR output if applicable."
+(defun exwm-workspace--set-fullscreen (frame &optional no-struts
+ container-only)
+ "Make frame FRAME fullscreen, with regard to its RandR output if applicable.
+
+If NO-STRUTS is non-nil, struts are ignored. If CONTAINER-ONLY is non-nil, the
+workspace frame and its container is not resized."
(let ((geometry (or (frame-parameter frame 'exwm-geometry)
(xcb:+request-unchecked+reply exwm--connection
(make-instance 'xcb:GetGeometry
@@ -153,24 +177,27 @@ Value nil means to use the default position which is
fixed at bottom, while
(workspace (frame-parameter frame 'exwm-workspace))
x* y* width* height*)
(with-slots (x y width height) geometry
- (if exwm-workspace--strut
- (setq x* (+ x (aref exwm-workspace--strut 0))
- y* (+ y (aref exwm-workspace--strut 2))
- width* (- width (aref exwm-workspace--strut 0)
- (aref exwm-workspace--strut 1))
- height* (- height (aref exwm-workspace--strut 2)
- (aref exwm-workspace--strut 3)))
+ (if (and exwm-workspace--struts (not no-struts))
+ (setq x* (+ x (aref exwm-workspace--struts 0))
+ y* (+ y (aref exwm-workspace--struts 2))
+ width* (- width (aref exwm-workspace--struts 0)
+ (aref exwm-workspace--struts 1))
+ height* (- height (aref exwm-workspace--struts 2)
+ (aref exwm-workspace--struts 3)))
(setq x* x
y* y
width* width
height* height))
(when (and (eq frame exwm-workspace--current)
- (exwm-workspace--minibuffer-own-frame-p))
+ (exwm-workspace--minibuffer-own-frame-p)
+ (not container-only))
(exwm-workspace--resize-minibuffer-frame width height))
- (exwm-layout--resize-container id container 0 0 width* height*)
+ (unless container-only
+ (exwm-layout--resize-container id container 0 0 width* height*))
(exwm-layout--resize-container nil workspace x* y* width* height* t)
(xcb:flush exwm--connection)))
- (cl-incf exwm-workspace--fullscreen-frame-count))
+ (unless container-only
+ (cl-incf exwm-workspace--fullscreen-frame-count)))
;;;###autoload
(defun exwm-workspace--resize-minibuffer-frame (&optional width height)
@@ -182,19 +209,19 @@ workspace frame."
(let ((y (if (eq exwm-workspace-minibuffer-position 'top)
0
(- (or height (exwm-workspace--current-height))
- (if exwm-workspace--strut
- (+ (aref exwm-workspace--strut 2)
- (aref exwm-workspace--strut 3))
+ (if exwm-workspace--struts
+ (+ (aref exwm-workspace--struts 2)
+ (aref exwm-workspace--struts 3))
0)
(frame-pixel-height exwm-workspace--minibuffer))))
(container (frame-parameter exwm-workspace--minibuffer
'exwm-container)))
(unless width
(setq width (exwm-workspace--current-width)))
- (when exwm-workspace--strut
+ (when exwm-workspace--struts
(setq width (- width
- (aref exwm-workspace--strut 0)
- (aref exwm-workspace--strut 1))))
+ (aref exwm-workspace--struts 0)
+ (aref exwm-workspace--struts 1))))
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window container
@@ -233,11 +260,22 @@ The optional FORCE option is for internal use only."
(let* ((frame (elt exwm-workspace--list index))
(workspace (frame-parameter frame 'exwm-workspace))
(window (frame-parameter frame 'exwm-selected-window)))
+ (unless (window-live-p window)
+ (setq window (frame-selected-window frame)))
+ ;; Raise the workspace container.
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window workspace
:value-mask xcb:ConfigWindow:StackMode
:stack-mode xcb:StackMode:Above))
+ ;; Raise X windows with struts set if there's no fullscreen X window.
+ (unless (buffer-local-value 'exwm--fullscreen (window-buffer window))
+ (dolist (pair exwm-workspace--id-struts-alist)
+ (xcb:+request exwm--connection
+ (make-instance 'xcb:ConfigureWindow
+ :window (car pair)
+ :value-mask xcb:ConfigWindow:StackMode
+ :stack-mode xcb:StackMode:Above))))
(setq exwm-workspace--current frame
exwm-workspace-current-index index)
(unless (memq (selected-frame) exwm-workspace--list)
@@ -245,8 +283,7 @@ The optional FORCE option is for internal use only."
(set-frame-parameter (with-current-buffer (window-buffer)
exwm--frame)
'exwm-selected-window (selected-window)))
- (select-window (or (when (window-live-p window) window)
- (frame-selected-window frame)))
+ (select-window window)
(set-frame-parameter frame 'exwm-selected-window nil)
;; Close the (possible) active minibuffer
(when (active-minibuffer-window)
@@ -556,9 +593,9 @@ The optional FORCE option is for internal use only."
y 0)
(setq value-mask (logior xcb:ConfigWindow:Y xcb:ConfigWindow:Height)
y (- (exwm-workspace--current-height)
- (if exwm-workspace--strut
- (+ (aref exwm-workspace--strut 2)
- (aref exwm-workspace--strut 3))
+ (if exwm-workspace--struts
+ (+ (aref exwm-workspace--struts 2)
+ (aref exwm-workspace--struts 3))
0)
height)))
(xcb:+request exwm--connection
@@ -731,13 +768,13 @@ The optional FORCE option is for internal use only."
(setq workareas (vconcat workareas workarea))))))
;; Exclude areas occupied by struts.
;; FIXME: RandR.
- (when exwm-workspace--strut
- (let ((dx (aref exwm-workspace--strut 0))
- (dy (aref exwm-workspace--strut 2))
- (dw (- (+ (aref exwm-workspace--strut 0)
- (aref exwm-workspace--strut 1))))
- (dh (- (+ (aref exwm-workspace--strut 2)
- (aref exwm-workspace--strut 3)))))
+ (when exwm-workspace--struts
+ (let ((dx (aref exwm-workspace--struts 0))
+ (dy (aref exwm-workspace--struts 2))
+ (dw (- (+ (aref exwm-workspace--struts 0)
+ (aref exwm-workspace--struts 1))))
+ (dh (- (+ (aref exwm-workspace--struts 2)
+ (aref exwm-workspace--struts 3)))))
(dotimes (i exwm-workspace-number)
(cl-incf (aref workareas (* i 4)) dx)
(cl-incf (aref workareas (+ (* i 4))) dy)
diff --git a/exwm.el b/exwm.el
index 3d7edcf..59f4313 100644
--- a/exwm.el
+++ b/exwm.el
@@ -227,45 +227,49 @@
(when reply ;nil when destroyed
(setq exwm--protocols (append (slot-value reply 'value) nil)))))))
-(defun exwm--update-strut-legacy (id)
+(defun exwm--update-struts-legacy (id)
"Update _NET_WM_STRUT."
- (unless exwm-workspace--strut-is-partial
- (let ((reply (xcb:+request-unchecked+reply exwm--connection
- (make-instance 'xcb:ewmh:get-_NET_WM_STRUT
- :window id))))
- (setq exwm-workspace--strut (when reply (slot-value reply 'value)))
+ (let ((pair (assq id exwm-workspace--id-struts-alist))
+ reply struts)
+ (unless (and pair (< 4 (length (cdr pair))))
+ (setq reply (xcb:+request-unchecked+reply exwm--connection
+ (make-instance 'xcb:ewmh:get-_NET_WM_STRUT
+ :window id)))
+ (when reply
+ (setq struts (slot-value reply 'value))
+ (if pair
+ (setcdr pair struts)
+ (push (cons id struts) exwm-workspace--id-struts-alist))
+ (exwm-workspace--update-struts))
;; Update workspaces.
(dolist (f exwm-workspace--list)
(exwm-workspace--set-fullscreen f))
- ;; Resize the minibuffer frame.
- (when (exwm-workspace--minibuffer-own-frame-p)
- (exwm-workspace--resize-minibuffer-frame))
;; Update _NET_WORKAREA.
(exwm-workspace--set-workareas))))
-(defun exwm--update-strut-partial (id)
+(defun exwm--update-struts-partial (id)
"Update _NET_WM_STRUT_PARTIAL."
(let ((reply (xcb:+request-unchecked+reply exwm--connection
(make-instance 'xcb:ewmh:get-_NET_WM_STRUT_PARTIAL
- :window id))))
- (setq exwm-workspace--strut (when reply (slot-value reply 'value)))
- (if (not exwm-workspace--strut)
- (setq exwm-workspace--strut-is-partial nil)
- (setq exwm-workspace--strut (substring exwm-workspace--strut 0 4))
- (setq exwm-workspace--strut-is-partial t))
+ :window id)))
+ struts pair)
+ (when reply
+ (setq struts (slot-value reply 'value)
+ pair (assq id exwm-workspace--id-struts-alist))
+ (if pair
+ (setcdr pair struts)
+ (push (cons id struts) exwm-workspace--id-struts-alist))
+ (exwm-workspace--update-struts))
;; Update workspaces.
(dolist (f exwm-workspace--list)
(exwm-workspace--set-fullscreen f))
- ;; Resize the minibuffer frame.
- (when (exwm-workspace--minibuffer-own-frame-p)
- (exwm-workspace--resize-minibuffer-frame))
;; Update _NET_WORKAREA.
(exwm-workspace--set-workareas)))
-(defun exwm--update-strut (id)
+(defun exwm--update-struts (id)
"Update _NET_WM_STRUT_PARTIAL or _NET_WM_STRUT."
- (exwm--update-strut-partial id)
- (exwm--update-strut-legacy id))
+ (exwm--update-struts-partial id)
+ (exwm--update-struts-legacy id))
(defun exwm--on-PropertyNotify (data _synthetic)
"Handle PropertyNotify event."
@@ -279,9 +283,9 @@
(if (not (buffer-live-p buffer))
;; Properties of unmanaged X windows.
(cond ((= atom xcb:Atom:_NET_WM_STRUT)
- (exwm--update-strut-legacy id))
+ (exwm--update-struts-legacy id))
((= atom xcb:Atom:_NET_WM_STRUT_PARTIAL)
- (exwm--update-strut-partial id)))
+ (exwm--update-struts-partial id)))
(with-current-buffer buffer
(cond ((= atom xcb:Atom:_NET_WM_WINDOW_TYPE)
(exwm--update-window-type id t))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/exwm 7f12d9f: Add multi-dock support and fix fullscreen issues with dock,
Chris Feng <=