Turning snap-window-position-to-edges into a policy



I have a hack in my personal .sawfishrc to replace the existing
snap-window-position-to-edges function.  This makes my screen
boundaries hard by default---dragging a window won't move it past the
end of the screen no matter how far the pointer displaces.  (In the
rare situations where I do want to go over the edge, I can turn off
all edge effects.)

  (defvar move-force-off-edges nil
    "Allow the window to move beyond the screen edges, even when
  MOVE-SNAP-EDGES is true.")

  (defun move-window-interactively-forced (w)
    "Move the window interactively using the mouse,
  ignoring root window boundaries."
    (interactive "%W")
    (let ((move-force-off-edges t))
      (move-window-interactively w)))

  (defun snap-window-position-to-edges (window coords deltas state
                                        #!optional epsilon edges mode)
    (let*
        ((dims (window-frame-dimensions window))
         (w-x-min (car coords))
         (w-x-max (+ (car coords) (car dims)))
         (w-y-min (cdr coords))
         (w-y-max (+ (cdr coords) (cdr dims)))
         (r-x-min 0)
         (r-x-max (screen-width))
         (r-y-min 0)
         (r-y-max (screen-height))
         (x-uf (- w-x-min r-x-min))
         (x-of (- w-x-max r-x-max))
         (y-uf (- w-y-min r-y-min))
         (y-of (- w-y-max r-y-max)))
      (setq coords (cons (car coords) (cdr coords)))
      (when (not move-force-off-edges)
        (when (< x-uf 0)
          (rplaca coords (- (car coords) x-uf)))
        (when (> x-of 0)
          (rplaca coords (- (car coords) x-of)))
        (when (< y-uf 0)
          (rplacd coords (- (cdr coords) y-uf)))
        (when (> y-of 0)
          (rplacd coords (- (cdr coords) y-of))))
      coords))

  ;; Big, big hack
  (eval-in `(setq snap-window-position-to-edges ,snap-window-position-to-edges)
           'sawfish.wm.util.edges)

What would people think about turning the edge behavior into a
configurable policy, beyond move-snap-epsilon?  From looking at the
current code, this would change the "motion" function in
move-resize.jl.  The

  (when (> move-snap-epsilon 0) ...)

block would turn into an invocation of a function bound to a defvar
variable, with the return value being the updated coordinates.  (Using
defvar will let me rebind the policy on the fly, as with
"move-window-interactively-forced" in my code above.)  The function
would take explicit parameters for "window", "coords" and "deltas".
Anything else it needs would come from defvars like
"move-resize-snap-state".

Comments?

Derek


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]