From 6be75083c2adeb54882061e82597fab4cdf2a4f4 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Fri, 23 Sep 2016 18:41:43 +0800 Subject: Use X window borders ; This commit replaces the internal borders of Emacs frames with X ; window borders. This should make the flickering issue of floating X ; windows less serious. * exwm-floating.el (exwm-floating--border-pixel) (exwm-floating--border-colormap): New variables for storing border pixel and its colormap. (exwm-floating--set-floating): Do not set the internal border (and background color) of floating frames; do not take `exwm-floating-border-width' into account when calculating geometries; set the border of floating X window containers. (exwm-floating--unset-floating): No need to restore the position of X windows any more; hide the border of floating X window containers. (exwm-floating--init): Initialize the border pixel. * exwm-layout.el (exwm-layout-set-fullscreen) (exwm-layout-unset-fullscreen): Show/Hide container border respectively. * exwm-manage.el (exwm-manage--manage-window): Set the border pixel and colormap of X window containers. * exwm-workspace.el (exwm-workspace-move-window): Do not set the internal border and background color of floating frames. * exwm.el (exwm--on-ClientMessage): Simplify the code for calculating _NET_REQUEST_FRAME_EXTENTS. --- exwm-floating.el | 56 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 16 deletions(-) (limited to 'exwm-floating.el') diff --git a/exwm-floating.el b/exwm-floating.el index 5b8cc89abc26..1780e5fc323b 100644 --- a/exwm-floating.el +++ b/exwm-floating.el @@ -32,6 +32,12 @@ (defvar exwm-floating-border-width 1 "Border width of the floating window.") (defvar exwm-floating-border-color "navy" "Border color of the floating window.") +(defvar exwm-floating--border-pixel nil + "Border pixel drawn around floating X windows.") +(defvar exwm-floating--border-colormap nil + "Colormap used by the border pixel. + +This is also used by X window containers.") (defvar exwm-floating-setup-hook nil "Normal hook run when an X window has been made floating, in the @@ -95,8 +101,6 @@ context of the corresponding buffer.") (get-buffer "*scratch*"))) (make-frame `((minibuffer . nil) ;use the default minibuffer. - (background-color . ,exwm-floating-border-color) - (internal-border-width . ,exwm-floating-border-width) (left . 10000) (top . 10000) (width . ,window-min-width) @@ -135,8 +139,7 @@ context of the corresponding buffer.") (window-pixel-height (minibuffer-window original-frame))) (* 2 (window-mode-line-height)) - (window-header-line-height window) - (* 2 exwm-floating-border-width))) + (window-header-line-height window))) (display-height (* 2 (/ display-height 2)))) ;round to even (if (> width display-width) ;; Too wide @@ -229,14 +232,17 @@ context of the corresponding buffer.") (make-instance 'xcb:ReparentWindow :window outer-id :parent frame-container :x 0 :y 0)) ;; Place the X window container. + ;; Also show the floating border. (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow :window container :value-mask (eval-when-compile (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y)) - :x (- x exwm-floating-border-width) - :y (- y exwm-floating-border-width))) + xcb:ConfigWindow:Y + xcb:ConfigWindow:BorderWidth)) + :x x + :y y + :border-width exwm-floating-border-width)) (exwm-floating--set-allowed-actions id nil) (xcb:flush exwm--connection) ;; Set window/buffer @@ -294,14 +300,6 @@ context of the corresponding buffer.") (make-instance 'xcb:ChangeWindowAttributes :window id :value-mask xcb:CW:EventMask :event-mask exwm--client-event-mask)) - ;; The X window might have been moved due to the floating border. - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window id - :value-mask (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y) - :x 0 - :y 0)) ;; Reparent the floating frame back to the root window. (let ((frame-id (frame-parameter exwm--floating-frame 'exwm-outer-id)) (frame-container (frame-parameter exwm--floating-frame @@ -318,11 +316,14 @@ context of the corresponding buffer.") (make-instance 'xcb:DestroyWindow :window frame-container)))) ;; Put the X window container just above the Emacs frame container ;; (the stacking order won't change from now on). + ;; Also hide the possible floating border. (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow :window exwm--container - :value-mask (logior xcb:ConfigWindow:Sibling + :value-mask (logior xcb:ConfigWindow:BorderWidth + xcb:ConfigWindow:Sibling xcb:ConfigWindow:StackMode) + :border-width 0 :sibling (frame-parameter exwm-workspace--current 'exwm-container) :stack-mode xcb:StackMode:Above))) @@ -681,6 +682,29 @@ Both DELTA-X and DELTA-Y default to 1. This command should be bound locally." (defun exwm-floating--init () "Initialize floating module." + ;; Check border width. + (unless (and (integerp exwm-floating-border-width) + (> exwm-floating-border-width 0)) + (setq exwm-floating-border-width 0)) + ;; Initialize border pixel. + (when (> exwm-floating-border-width 0) + (setq exwm-floating--border-colormap + (slot-value (car (slot-value + (xcb:get-setup exwm--connection) 'roots)) + 'default-colormap)) + (unless (stringp exwm-floating-border-color) + (setq exwm-floating-border-color "")) + (let* ((color (x-color-values exwm-floating-border-color)) + reply) + (when color + (setq reply (xcb:+request-unchecked+reply exwm--connection + (make-instance 'xcb:AllocColor + :cmap exwm-floating--border-colormap + :red (pop color) + :green (pop color) + :blue (pop color)))) + (when reply + (setq exwm-floating--border-pixel (slot-value reply 'pixel)))))) ;; Initialize cursors for moving/resizing a window (xcb:cursor:init exwm--connection) (setq exwm-floating--cursor-move -- cgit 1.4.1