Re: dynamic viewports
- From: Jeremy Hankins <nowan nowan org>
- To: General discussion about sawfish wm <sawfish-list gnome org>
- Subject: Re: dynamic viewports
- Date: Thu, 27 Aug 2009 13:22:25 -0500
Christopher Roy Bratusek <zanghar freenet de> writes:
> no patch?
Yeah, lets try that again. :P
-------------------------------------
diff --git a/lisp/sawfish/wm/viewport.jl b/lisp/sawfish/wm/viewport.jl
index 117ff2b..054b5ae 100644
--- a/lisp/sawfish/wm/viewport.jl
+++ b/lisp/sawfish/wm/viewport.jl
@@ -35,6 +35,7 @@
window-viewport
window-absolute-position
set-number-of-viewports
+ viewport-minimum-size-changed
viewport-windows)
(open rep
@@ -57,7 +58,7 @@
"Number of columns and rows in each virtual workspace: \\w"
:group (workspace viewport)
:type (pair (number 1) (number 1))
- :after-set (lambda () (viewport-size-changed)))
+ :after-set (lambda () (viewport-size-changed t)))
(defcustom viewport-minimum-dimensions '(1 . 1)
"Minimum number of columns and rows in each virtual workspace: \\w"
@@ -77,10 +78,14 @@
:range (1 . 50))
(defcustom viewport-boundary-mode 'stop
- "Whether to stop or wrap-around on first/last viewport"
+ "Whether to stop, wrap-around, or grow the virtual workspace on
+first/last viewport"
:group (workspace viewport)
:type (choice wrap-around stop dynamic))
+ (defvar workspace-viewport-data nil
+ "Information about the viewport details of different workspaces.")
+
;;; raw viewport handling
(defvar viewport-x-offset 0)
@@ -106,7 +111,12 @@
;; ..then move away the windows on the old viewport,
;; in bottom-to-top order
(mapc move-window inside)))
-
+ ;; No need to warp windows not in the current workspace.
+ ;; See viewport-leave-workspace-handler and
+ ;; viewport-enter-workspace handler below.
+ ((not
+ (window-appears-in-workspace-p (car rest) current-workspace))
+ (loop (cdr rest) inside outside))
((window-outside-viewport-p (car rest))
(loop (cdr rest) inside (cons (car rest) outside)))
@@ -134,6 +144,8 @@ The scrolling makes a number of increments equal to `scroll-viewport-steps'."
(add-hook 'before-exit-hook viewport-before-exiting t)
(define (viewport-dynamic-resize)
+ "Reset the size of the viewport to include the current screen as
+well as any windows in the current workspace."
(when (eq viewport-boundary-mode 'dynamic)
(let ((windows
(filter-windows
@@ -141,7 +153,9 @@ The scrolling makes a number of increments equal to `scroll-viewport-steps'."
(window-in-workspace-p w current-workspace)))))
(if windows
(let*
- ((points
+ ((width (screen-width))
+ (height (screen-height))
+ (points
(nconc
(mapcar (lambda (w)
(let ((pos (window-position w))
@@ -151,39 +165,45 @@ The scrolling makes a number of increments equal to `scroll-viewport-steps'."
(+ (car pos) (car dims))
(+ (cdr pos) (cdr dims)))))
windows)
- ;; Include a region in the current screen:
- `((0 0 1 1))))
- (x-min (apply min (mapcar car points)))
- (y-min (apply min (mapcar (lambda (e) (nth 1 e)) points)))
- (x-max (apply max (mapcar (lambda (e) (nth 2 e)) points)))
- (y-max (apply max (mapcar (lambda (e) (nth 3 e)) points)))
- (width (screen-width))
- (height (screen-height))
+ ;; Include the current screen:
+ `((0 0 ,(1- width) ,(1- height)))))
+ ;; The min/max values calculated below are relative to
+ ;; the old logical 0,0 point of the virtual desktop:
+ (old-x-origin (- viewport-x-offset))
+ (old-y-origin (- viewport-y-offset))
+ (x-min (- (apply min (mapcar car points)) old-x-origin))
+ (y-min (- (apply min (mapcar (lambda (e) (nth 1 e)) points))
+ old-y-origin))
+ (x-max (- (apply max (mapcar (lambda (e) (nth 2 e)) points))
+ old-x-origin))
+ (y-max (- (apply max (mapcar (lambda (e) (nth 3 e)) points))
+ old-y-origin))
+ ;; high-* values are the number of rows/columns above
+ ;; the old origin, low-* values the number below the
+ ;; old origin.
(high-rows (+ (quotient y-max height)
- (if (> (mod y-max height) 0)
- 1
- 0)))
- (low-rows (if (< y-min 0)
- (+ (- (quotient y-min height))
- (if (> (mod y-min height) 0)
- 1
- 0))
- 0))
+ (if (> (mod y-max height) 0)
+ 1
+ 0)))
+ (low-rows (+ (- (quotient y-min height))
+ (if (and (< y-min 0)
+ (> (mod y-min height) 0))
+ 1
+ 0)))
(rows (+ low-rows high-rows))
(high-cols (+ (quotient x-max width)
(if (> (mod x-max width) 0)
1
0)))
- (low-cols (if (< x-min 0)
- (+ (- (quotient x-min width))
- (if (> (mod x-min width) 0)
- 1
- 0))
- 0))
+ (low-cols (+ (- (quotient x-min width))
+ (if (and (< x-min 0)
+ (> (mod x-min width) 0))
+ 1
+ 0)))
(cols (+ low-cols high-cols)))
(setq
- viewport-y-offset (* low-rows height)
- viewport-x-offset (* low-cols width)
+ viewport-y-offset (- (- old-y-origin (* low-rows height)))
+ viewport-x-offset (- (- old-x-origin (* low-cols width)))
viewport-dimensions (cons
(max cols
(car viewport-minimum-dimensions))
@@ -194,14 +214,55 @@ The scrolling makes a number of increments equal to `scroll-viewport-steps'."
viewport-dimensions viewport-minimum-dimensions))
(call-hook 'viewport-resized-hook))))
- ;; Resize virtual workspace on workspace switch or viewport move.
- ;; TODO: Ensure that the viewport is set reasonably in the new
- ;; workspace.
- (add-hook 'enter-workspace-hook
- viewport-dynamic-resize)
+ ;; Resize virtual workspace on workspace switch or viewport move:
(add-hook 'viewport-moved-hook
viewport-dynamic-resize)
+ (define (viewport-leave-workspace-handler ws)
+ "On leaving a workspace, store information about the viewport
+configuration so that it can be restored properly later."
+ (let ((vp-data (list viewport-y-offset
+ viewport-x-offset
+ viewport-dimensions))
+ (old-ent (assoc ws workspace-viewport-data)))
+ (if old-ent
+ (rplacd old-ent vp-data)
+ (setq workspace-viewport-data
+ (cons (cons ws vp-data)
+ workspace-viewport-data)))))
+
+ (add-hook 'leave-workspace-hook
+ viewport-leave-workspace-handler)
+
+ (define (viewport-enter-workspace-handler ws)
+ "Restore any saved data about the viewport for the new workspace.
+When `viewport-boundary-mode' is not `dynamic', make sure that the new
+viewport is within `viewport-dimensions'."
+ (let ((vp-data (cdr (assoc ws workspace-viewport-data))))
+ (if vp-data
+ (let ((maybe-y-offset (car vp-data))
+ (maybe-x-offset (nth 1 vp-data)))
+ (if (eq viewport-boundary-mode 'dynamic)
+ (setq viewport-dimensions (nth 2 vp-data)
+ viewport-y-offset maybe-y-offset
+ viewport-x-offset maybe-x-offset)
+ ;; Do maybe-y-offset and maybe-x-offset fit within
+ ;; current viewport-dimensions?
+ (if (and (<= maybe-y-offset
+ (* (1- (car viewport-dimensions)) (screen-height)))
+ (<= maybe-x-offset
+ (* (1- (cdr viewport-dimensions)) (screen-width))))
+ (setq viewport-y-offset maybe-y-offset
+ viewport-x-offset maybe-x-offset)
+ (setq viewport-y-offset 0
+ viewport-x-offset 0))))
+ (setq viewport-y-offset 0
+ viewport-x-offset 0))
+ (viewport-size-changed)))
+
+ (add-hook 'enter-workspace-hook
+ viewport-enter-workspace-handler)
+
;; screen sized viewport handling
(define (screen-viewport)
@@ -297,22 +358,37 @@ The scrolling makes a number of increments equal to `scroll-viewport-steps'."
(mod (+ (cdr position) viewport-y-offset) (screen-height)))
position)))
- (define (viewport-size-changed)
+ (define (viewport-size-changed #!optional force)
+ ;; This is called when the user requests a change (e.g., from the
+ ;; gui, or via `set-number-of-viewports') as well as when the
+ ;; desktop is switched. If `force' is set it's considered to be
+ ;; user-requested, and therefore mandatory that the
+ ;; `viewport-dimensions' variable be respected.
(when (or (< (car viewport-dimensions) (car viewport-minimum-dimensions))
(< (cdr viewport-dimensions) (cdr viewport-minimum-dimensions)))
- (setq viewport-minimum-dimensions
- (cons (min (car viewport-dimensions)
- (car viewport-minimum-dimensions))
- (min (cdr viewport-dimensions)
- (cdr viewport-minimum-dimensions))))
+ (if force
+ (setq viewport-minimum-dimensions
+ (cons (min (car viewport-dimensions)
+ (car viewport-minimum-dimensions))
+ (min (cdr viewport-dimensions)
+ (cdr viewport-minimum-dimensions))))
+ (setq viewport-dimensions
+ (cons (max (car viewport-dimensions)
+ (car viewport-minimum-dimensions))
+ (max (cdr viewport-dimensions)
+ (cdr viewport-minimum-dimensions)))))
(when (eq viewport-boundary-mode 'dynamic)
(viewport-dynamic-resize)))
(unless (eq viewport-boundary-mode 'dynamic)
+ ;; Not using dynmic viewports, so ensure that windows are within
+ ;; the current virtual-workspace boundaries:
(let ((port (screen-viewport)))
(set-screen-viewport (min (car port) (1- (car viewport-dimensions)))
(min (cdr port) (1- (cdr viewport-dimensions))))
(map-windows (lambda (w)
- (when (window-outside-workspace-p w)
+ (when (and (window-outside-workspace-p w)
+ (window-appears-in-workspace-p
+ w current-workspace))
(move-window-to-current-viewport w))))
(call-hook 'viewport-resized-hook))))
@@ -333,7 +409,7 @@ The scrolling makes a number of increments equal to `scroll-viewport-steps'."
(setq viewport-minimum-dimensions (cons width height))
(if (eq viewport-boundary-mode 'dynamic)
(viewport-dynamic-resize)
- (viewport-size-changed)))
+ (viewport-size-changed t)))
(define (viewport-windows #!optional vp-col vp-row workspace
exclude-sticky exclude-iconified)
diff --git a/man/sawfish.texi b/man/sawfish.texi
index f16b663..b66d1c0 100644
--- a/man/sawfish.texi
+++ b/man/sawfish.texi
@@ -3842,6 +3842,17 @@ This is a cons cell @code{(@var{across} . @var{down})}. Defaults to
@code{(1 . 1)}.
@end defvar
+ defvar viewport-minimum-dimensions
+This is only useful if @code{viewport-boundary-mode} is set to
+ code{dynamic}, otherwise it is automatically set to the same value as
+viewport-dimensions. If @code{viewport-boundary-mode} is set to
+ code{dynamic} then @code{viewport-dimensions} will never shrink to
+less than @code{viewport-minimum-dimensions}. If setting
+ code{viewport-minimum-dimensions} by hand (not by the customization
+interface) be sure to call @code{viewport-minimum-size-changed} after
+doing so.
+ end defvar
+
@defun set-number-of-viewports width height
Change @code{viewport-dimensions} to have the value
@code{(@var{width} . @var{height})}.
@@ -3885,9 +3896,11 @@ that is outside of @code{viewport-dimensions}. When set to
@code{wrap-around}, it loops in the vertical and horizontal axes
enough times to keep the viewport within the defined dimensions. When
set to @code{stop}, it refuses to switch to a viewport outside of
- code{viewport-dimensions}, if set to @code{dynamic}, it will create a
-new viewport at the side the pointer hit the screen-edge.
-Defaults to @code{wrap-around}.
+ code{viewport-dimensions} If it is set to @code{dynamic} it
+automatically resizes @code{viewport-dimensions} to permit the move
+and eliminate unneeded rows or columns, down to the minimum dimensions
+specified by @code{viewport-minimum-dimensions}. Defaults to
+ code{wrap-around}
@end defvar
@defun warp-viewport x y
-------------------------------------
--
Jeremy Hankins <nowan nowan org>
PGP fingerprint: 748F 4D16 538E 75D6 8333 9E10 D212 B5ED 37D0 0A03
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]