index

How does Sawfish distribute focus:

sloppy focus

primary question: where to listen for events?

How to answer? by looking at the specification, and our requirements:

1/ we want to know which top level window "has the focus" (i.e. it's descendant).

so, we have to listen on a boundary separating top windows: all the frame windows. Common least ancestor is the Root. could we listen only on the root? no. Only ev->xfocus.window. If we listened on the client window, we might receive a lot of useless events, focus changing between the top client window and its descendants.

But what if the window is not framed?

News from 15 mag 06

I now listen on focus events on the `client' windows. This is b/c when the client win. is destroyed, first I receive Focus-out, then DestroyNotify (and here I want to forget about the window), and only then Focus-In/out from the Frame window. Acting on this 3rd event would mean that I need to keep the "lispWindow" even after DestroyNotify.

what & where to grab?

anykey/anymodifier on the frame!

when a window closes, it might Grab & destroy (unmap). thus, we will inherit the grab on next key event. a bit hacky.

send-to-workspace

unmaps the frame window (not the client window), so it doesn't trigger the unmap-notify-hook, which is responsible for focusing another window. No other program can unmap the frame window. So it's reasonable to act on the unmap-notify of the frame. But: if the input focus is in the client window with revert_to set to anything by the application, the focus_out event can arrive after the unamp-notify event. So this would override our request. And if the newly focused window is closed too, and is non-managed (w/ override_redirect), the focus goes to Root.

how focus is travelling:

We indicate focus changes. For each change we either receive a confirmation, or error.

Sometimes an action, our, or user's leads to focus change. Either change goes to another window or to Root/None.

So, we play focus-out-hook. And, if needed (None), select another window to focus.

Optimization: we know when the focused window will lose its focus: When we unmap it.

Variables:

hooks

/* We can lose the focus sometimes, notably after a was-focused window is closed while a keyboard grab exists.. (netscape) /

check_for_lost_focus (void)

windows.c

Lisp_Window focus_window; / where is the X focus. modified on focus_out/in events / It is the lisp window: the X window is the client or the frame!

I think I lost the last hope on getting focus handling independent of time (speed of communication): Imagine window A is closed, and B is its prefered successor for focus. So SF requests focus for B, but lets imagine that windows B and (another) C is closed (in that order) "immediately" after A. So X server sends error to SF, and now.... there are 2 ways: either C window destroyNotify arrives before the focus error, in which case the focus successor is selected among windows out of [A, B, C] or the error (for focusing a gone window) arrives before the destroyNotify of C, in which case the successor of B might be also C.

i wanted to avoid the flickering (multiple focus-in/out for the right window), so i changed: void focus_on_window (Lisp_Window w) {

// mmc: wtf ?? // commit_queued_focus_change();

then i started to have problems w/ (much) delayed focus !!!

lost-focus-hook is executed when i prompt (for wid) ... wrong

reverttoNone ... cannot grabKey -> wrong

* error handler:

BadWindow ->

does it destry the lisp DS of the window?

WINDOW_IS_GONE_P(w) (w->id == 0)

remove_window

Changing-focus lisp functions & related hooks

base set-input-focus Invokes my new set-focus-hook

But there is: activate-window and activate-window-hook: This does:

focus-in-fun calls (window-order-push w) ! duplicated!

Another one display-window:

Implication for Themes:

It seems that I found a hack to avoid the theme flickering. When a frame part is exposed, b/c a window is raised, it is redrawn based on whether the window is focused. The test checks if the window has received Focus_In. Now I test, whether that is the (last) window we have requested focus for.