mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-27 14:57:59 +01:00
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…
Reference in a new issue