Implement move/resize with keyboard
* exwm-floating.el: Remove an invalid TODO item. * exwm-floating.el (exwm-floating--set-floating) (exwm-floating-hide-mode-line, exwm-floating-show-mode-line): Set window-size-fixed only for fixed-size floating windows. * exwm-floating.el (exwm-floating-move): New function for moving a floating window. * exwm-layout.el (exwm-layout-enlarge-window) (exwm-layout-enlarge-window-horizontally, exwm-layout-shrink-window) (exwm-layout-shrink-window-horizontally): New commands for interactively resizing a floating window.
This commit is contained in:
		
							parent
							
								
									1d435157d3
								
							
						
					
					
						commit
						dbcabe7946
					
				
					 2 changed files with 123 additions and 8 deletions
				
			
		| 
						 | 
					@ -24,9 +24,6 @@
 | 
				
			||||||
;; This module deals with the conversion between floating and non-floating
 | 
					;; This module deals with the conversion between floating and non-floating
 | 
				
			||||||
;; states and implements moving/resizing operations on floating windows.
 | 
					;; states and implements moving/resizing operations on floating windows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; Todo:
 | 
					 | 
				
			||||||
;; + move/resize with keyboard.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
;;; Code:
 | 
					;;; Code:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(require 'xcb-cursor)
 | 
					(require 'xcb-cursor)
 | 
				
			||||||
| 
						 | 
					@ -184,7 +181,7 @@
 | 
				
			||||||
    (xcb:flush exwm--connection)
 | 
					    (xcb:flush exwm--connection)
 | 
				
			||||||
    ;; Set window/buffer
 | 
					    ;; Set window/buffer
 | 
				
			||||||
    (with-current-buffer (exwm--id->buffer id)
 | 
					    (with-current-buffer (exwm--id->buffer id)
 | 
				
			||||||
      (setq window-size-fixed t         ;make frame fixed size
 | 
					      (setq window-size-fixed exwm--fixed-size
 | 
				
			||||||
            exwm--frame original-frame
 | 
					            exwm--frame original-frame
 | 
				
			||||||
            exwm--floating-frame frame)
 | 
					            exwm--floating-frame frame)
 | 
				
			||||||
      (set-window-buffer window (current-buffer)) ;this changes current buffer
 | 
					      (set-window-buffer window (current-buffer)) ;this changes current buffer
 | 
				
			||||||
| 
						 | 
					@ -242,8 +239,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Default to resize `exwm--floating-frame' unless FRAME-OUTER-ID is non-nil.
 | 
					Default to resize `exwm--floating-frame' unless FRAME-OUTER-ID is non-nil.
 | 
				
			||||||
This function will issue an `xcb:GetGeometry' request unless WIDTH and HEIGHT
 | 
					This function will issue an `xcb:GetGeometry' request unless WIDTH and HEIGHT
 | 
				
			||||||
are provided. You should call `xcb:flush' and assign `window-size-fixed' a
 | 
					are provided. You should call `xcb:flush' and restore the value of
 | 
				
			||||||
non-nil value afterwards."
 | 
					`window-size-fixed' afterwards."
 | 
				
			||||||
  (setq window-size-fixed nil)
 | 
					  (setq window-size-fixed nil)
 | 
				
			||||||
  (unless (and width height)
 | 
					  (unless (and width height)
 | 
				
			||||||
    (let ((geometry (xcb:+request-unchecked+reply exwm--connection
 | 
					    (let ((geometry (xcb:+request-unchecked+reply exwm--connection
 | 
				
			||||||
| 
						 | 
					@ -274,7 +271,7 @@ non-nil value afterwards."
 | 
				
			||||||
          mode-line-format nil)
 | 
					          mode-line-format nil)
 | 
				
			||||||
    (exwm-floating--fit-frame-to-window)
 | 
					    (exwm-floating--fit-frame-to-window)
 | 
				
			||||||
    (xcb:flush exwm--connection)
 | 
					    (xcb:flush exwm--connection)
 | 
				
			||||||
    (setq window-size-fixed t)))
 | 
					    (setq window-size-fixed exwm--fixed-size)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defun exwm-floating-show-mode-line ()
 | 
					(defun exwm-floating-show-mode-line ()
 | 
				
			||||||
  "Show mode-line of a floating frame."
 | 
					  "Show mode-line of a floating frame."
 | 
				
			||||||
| 
						 | 
					@ -287,7 +284,7 @@ non-nil value afterwards."
 | 
				
			||||||
    (exwm-floating--fit-frame-to-window)
 | 
					    (exwm-floating--fit-frame-to-window)
 | 
				
			||||||
    (exwm-input-grab-keyboard)       ;mode-line-format may be outdated
 | 
					    (exwm-input-grab-keyboard)       ;mode-line-format may be outdated
 | 
				
			||||||
    (xcb:flush exwm--connection)
 | 
					    (xcb:flush exwm--connection)
 | 
				
			||||||
    (setq window-size-fixed t)))
 | 
					    (setq window-size-fixed exwm--fixed-size)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defvar exwm-floating--moveresize-calculate nil
 | 
					(defvar exwm-floating--moveresize-calculate nil
 | 
				
			||||||
  "Calculate move/resize parameters [frame-id event-mask x y width height].")
 | 
					  "Calculate move/resize parameters [frame-id event-mask x y width height].")
 | 
				
			||||||
| 
						 | 
					@ -462,6 +459,27 @@ non-nil value afterwards."
 | 
				
			||||||
                         :width (elt result 4) :height (elt result 5)))
 | 
					                         :width (elt result 4) :height (elt result 5)))
 | 
				
			||||||
      (xcb:flush exwm--connection))))
 | 
					      (xcb:flush exwm--connection))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defun exwm-floating-move (&optional delta-x delta-y)
 | 
				
			||||||
 | 
					  "Move a floating window right by DELTA-X pixels and down by DELTA-Y pixels.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Both DELTA-X and DELTA-Y default to 1.  This command should be bound locally."
 | 
				
			||||||
 | 
					  (unless (and (eq major-mode 'exwm-mode) exwm--floating-frame)
 | 
				
			||||||
 | 
					    (user-error "[EXWM] `exwm-floating-move' is only for floating X windows"))
 | 
				
			||||||
 | 
					  (unless delta-x (setq delta-x 1))
 | 
				
			||||||
 | 
					  (unless delta-y (setq delta-y 1))
 | 
				
			||||||
 | 
					  (unless (and (= 0 delta-x) (= 0 delta-y))
 | 
				
			||||||
 | 
					    (let* ((id (frame-parameter exwm--floating-frame 'exwm-outer-id))
 | 
				
			||||||
 | 
					           (geometry (xcb:+request-unchecked+reply exwm--connection
 | 
				
			||||||
 | 
					                         (make-instance 'xcb:GetGeometry :drawable id))))
 | 
				
			||||||
 | 
					      (xcb:+request exwm--connection
 | 
				
			||||||
 | 
					          (make-instance 'xcb:ConfigureWindow
 | 
				
			||||||
 | 
					                         :window id
 | 
				
			||||||
 | 
					                         :value-mask (logior xcb:ConfigWindow:X
 | 
				
			||||||
 | 
					                                             xcb:ConfigWindow:Y)
 | 
				
			||||||
 | 
					                         :x (+ (slot-value geometry 'x) delta-x)
 | 
				
			||||||
 | 
					                         :y (+ (slot-value geometry 'y) delta-y))))
 | 
				
			||||||
 | 
					    (xcb:flush exwm--connection)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defun exwm-floating--init ()
 | 
					(defun exwm-floating--init ()
 | 
				
			||||||
  "Initialize floating module."
 | 
					  "Initialize floating module."
 | 
				
			||||||
  ;; Initialize cursors for moving/resizing a window
 | 
					  ;; Initialize cursors for moving/resizing a window
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -263,6 +263,103 @@
 | 
				
			||||||
                                              exwm--floating-frame)))
 | 
					                                              exwm--floating-frame)))
 | 
				
			||||||
                           (exwm-layout--refresh)))))
 | 
					                           (exwm-layout--refresh)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defun exwm-layout-enlarge-window (delta &optional horizontal)
 | 
				
			||||||
 | 
					  "Make the selected window DELTA pixels taller.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If no argument is given, make the selected window one pixel taller.  If the
 | 
				
			||||||
 | 
					optional argument HORIZONTAL is non-nil, make selected window DELTA pixels
 | 
				
			||||||
 | 
					wider.  If DELTA is negative, shrink selected window by -DELTA pixels.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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")
 | 
				
			||||||
 | 
					  (cond
 | 
				
			||||||
 | 
					   ((zerop delta))                     ;no operation
 | 
				
			||||||
 | 
					   ((window-minibuffer-p))             ;avoid resize minibuffer-window
 | 
				
			||||||
 | 
					   ((not (and (eq major-mode 'exwm-mode) exwm--floating-frame))
 | 
				
			||||||
 | 
					    ;; Resize on tiling layout
 | 
				
			||||||
 | 
					    (unless (= 0 (window-resizable nil delta horizontal nil t)) ;not resizable
 | 
				
			||||||
 | 
					      (let ((window-resize-pixelwise t))
 | 
				
			||||||
 | 
					        (window-resize nil delta horizontal nil t))))
 | 
				
			||||||
 | 
					   ;; Resize on floating layout
 | 
				
			||||||
 | 
					   (exwm--fixed-size)                   ;fixed size
 | 
				
			||||||
 | 
					   (horizontal
 | 
				
			||||||
 | 
					    (let* ((width (frame-pixel-width))
 | 
				
			||||||
 | 
					           (edges (window-inside-pixel-edges))
 | 
				
			||||||
 | 
					           (inner-width (- (elt edges 2) (elt edges 0)))
 | 
				
			||||||
 | 
					           (margin (- width inner-width)))
 | 
				
			||||||
 | 
					      (if (> delta 0)
 | 
				
			||||||
 | 
					          (if (not exwm--normal-hints-max-width)
 | 
				
			||||||
 | 
					              (cl-incf width delta)
 | 
				
			||||||
 | 
					            (if (>= inner-width exwm--normal-hints-max-width)
 | 
				
			||||||
 | 
					                (setq width nil)
 | 
				
			||||||
 | 
					              (setq width (min (+ exwm--normal-hints-max-width margin)
 | 
				
			||||||
 | 
					                               (+ width delta)))))
 | 
				
			||||||
 | 
					        (if (not exwm--normal-hints-min-width)
 | 
				
			||||||
 | 
					            (cl-incf width delta)
 | 
				
			||||||
 | 
					          (if (<= inner-width exwm--normal-hints-min-width)
 | 
				
			||||||
 | 
					              (setq width nil)
 | 
				
			||||||
 | 
					            (setq width (max (+ exwm--normal-hints-min-width margin)
 | 
				
			||||||
 | 
					                             (+ width delta))))))
 | 
				
			||||||
 | 
					      (when width
 | 
				
			||||||
 | 
					        (setq exwm--floating-edges nil) ;invalid from now on
 | 
				
			||||||
 | 
					        (xcb:+request exwm--connection
 | 
				
			||||||
 | 
					            (make-instance 'xcb:ConfigureWindow
 | 
				
			||||||
 | 
					                           :window (frame-parameter exwm--floating-frame
 | 
				
			||||||
 | 
					                                                    'exwm-outer-id)
 | 
				
			||||||
 | 
					                           :value-mask xcb:ConfigWindow:Width
 | 
				
			||||||
 | 
					                           :width width))
 | 
				
			||||||
 | 
					        (xcb:flush exwm--connection))))
 | 
				
			||||||
 | 
					   (t
 | 
				
			||||||
 | 
					    (let* ((height (frame-pixel-height))
 | 
				
			||||||
 | 
					           (edges (window-inside-pixel-edges))
 | 
				
			||||||
 | 
					           (inner-height (- (elt edges 3) (elt edges 1)))
 | 
				
			||||||
 | 
					           (margin (- height inner-height)))
 | 
				
			||||||
 | 
					      (if (> delta 0)
 | 
				
			||||||
 | 
					          (if (not exwm--normal-hints-max-height)
 | 
				
			||||||
 | 
					              (cl-incf height delta)
 | 
				
			||||||
 | 
					            (if (>= inner-height exwm--normal-hints-max-height)
 | 
				
			||||||
 | 
					                (setq height nil)
 | 
				
			||||||
 | 
					              (setq height (min (+ exwm--normal-hints-max-height margin)
 | 
				
			||||||
 | 
					                                (+ height delta)))))
 | 
				
			||||||
 | 
					        (if (not exwm--normal-hints-min-height)
 | 
				
			||||||
 | 
					            (cl-incf height delta)
 | 
				
			||||||
 | 
					          (if (<= inner-height exwm--normal-hints-min-height)
 | 
				
			||||||
 | 
					              (setq height nil)
 | 
				
			||||||
 | 
					            (setq height (max (+ exwm--normal-hints-min-height margin)
 | 
				
			||||||
 | 
					                              (+ height delta))))))
 | 
				
			||||||
 | 
					      (when height
 | 
				
			||||||
 | 
					        (setq exwm--floating-edges nil) ;invalid from now on
 | 
				
			||||||
 | 
					        (xcb:+request exwm--connection
 | 
				
			||||||
 | 
					            (make-instance 'xcb:ConfigureWindow
 | 
				
			||||||
 | 
					                           :window (frame-parameter exwm--floating-frame
 | 
				
			||||||
 | 
					                                                    'exwm-outer-id)
 | 
				
			||||||
 | 
					                           :value-mask xcb:ConfigWindow:Height
 | 
				
			||||||
 | 
					                           :height height))
 | 
				
			||||||
 | 
					        (xcb:flush exwm--connection))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defun exwm-layout-enlarge-window-horizontally (delta)
 | 
				
			||||||
 | 
					  "Make the selected window DELTA pixels wider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See also `exwm-layout-enlarge-window'."
 | 
				
			||||||
 | 
					  (interactive "p")
 | 
				
			||||||
 | 
					  (exwm-layout-enlarge-window delta t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defun exwm-layout-shrink-window (delta)
 | 
				
			||||||
 | 
					  "Make the selected window DELTA pixels lower.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See also `exwm-layout-enlarge-window'."
 | 
				
			||||||
 | 
					  (interactive "p")
 | 
				
			||||||
 | 
					  (exwm-layout-enlarge-window (- delta)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(defun exwm-layout-shrink-window-horizontally (delta)
 | 
				
			||||||
 | 
					  "Make the selected window DELTA pixels narrower.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See also `exwm-layout-enlarge-window'."
 | 
				
			||||||
 | 
					  (interactive "p")
 | 
				
			||||||
 | 
					  (exwm-layout-enlarge-window (- delta) t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(defun exwm-layout--init ()
 | 
					(defun exwm-layout--init ()
 | 
				
			||||||
  "Initialize layout module."
 | 
					  "Initialize layout module."
 | 
				
			||||||
  ;; Auto refresh layout
 | 
					  ;; Auto refresh layout
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue