Re: Learning to program sawfish

* Rodrigo Amestica [2008-09-04 20:04+0200] writes:

> (setq focus-mode 'click)
> (move-window-to w (car tpos1) (cdr tpos1))
> (setq focus-mode 'enter-only)
> My thinking was like this: if the mouse is at the edge of the window
> and the next motion will move the window away from it and it also
> happens that there is an other window right below there then my moved
> window will lose focus. I do not want that to happen. Then very
> cleverly, I thought, let's change the focus mode, move the window and
> then revert to the original focus mode. Well, this does not work. It
> seems that  move-window-to has not really completed moving the window
> after it has returned.

Yes, you are right.  Sawfish sends a move request, but doesn't wait for
any reply.  When the X-server receives the request, it moves the window
and sends some events (configure, expose etc.).  Sawfish processes those
events after your code has completed, and adjusts the focus in response
to those events.

This also explains why changing the focus mode doesn't work.  The focus
mode is (again) enter-only when the event handlers run.

If you look a the source of the cycle commands, you will find that those
commands temporarily set focus-ignore-pointer-events to nil.  It works
something like so:

  (make-timer (lambda () (setq focus-ignore-pointer-events nil))
	      0 100)
  (setq focus-ignore-pointer-events t)
  (move-window-to WIN X Y)

> For a moment I thought that the *-grabbed functions would help me, but
> they did not and I do not really understand what exactly they are
> doing.

I think that grabbing would work if the focus were changed in response
to keyboard/mouse events.  I guess though that, Sawfish moves the focus
in response to configure/expose events.

> Then I thought I should use hooks. Install a hook, move the window,
> let the hook detect things and uninstall the hook from the hook
> itself. But this sounds to convoluted. Not sure something like this is
> the right approach.

A problem is that we need to wait for events.  The only way to wait that
I know is `recursive-edit'. [I learned the hard way that `sit-for'
doesn't work in Sawfish.]  Something like this could work:

  (letrec ((hook (lambda (win)
                   (message "configure-notify-hook called")
                   (window-put win 
                               (remove hook
                                       (window-get win 
                   (throw 'exit-recursive-edit nil))))
      (window-put WIN 'configure-notify-hook
                  (cons hook (window-get WIN 'configure-notify-hook)))
      (move-window-to WIN X Y)
      (let ((focus-ignore-pointer-events t))
        (catch 'exit-recursive-edit

But, yeah, it's clumsy.  (And throw/catch can unintentionally cross
multiple recursive-edit levels.)

> There is something about the 'mechanics' of sawfish that I cannot
> grasp and which I have not being able to find somehow described in the
> documentation and older postings.

Despite reading the source, it helps to know a little bit about X and
Xlib, e.g. it's essential to know that Sawfish can send requests, but
(usually) reacts on the replies only in event handlers.


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