Hi, Sawfish list. Let me send two patches to fix focus bugs.

The first one is for the notorious "enter-exit flickers" issue, and the second 
one for that after invocation of commands in x-cycle.jl (like cycle-windows and 
cycle-windows-backwards, and variants like -group and -among-group, etc), focus 
changes by pointer motion get ignored in focus-* modes.

At least both work correctly for me, but my test is far from thorough.

1. "enter-exit flickers" is fixed by ignoring "pointer-out". It may seem 
necessary, but reacting to "pointer-in" and "enter-root" is enough. The fixed 
symptoms are described in the patch commit log.

This patch is formed against HEAD, but it seems to work also for pre-9bdc8, 
which was a change to focus.jl in last November. (I don't know the exact 
symptom described in 9bdc8. It seems similar to mine, but it tries to fix both 
enter-exit and enter-only. Mine is related only to enter-exit.)

2. The fix of x-cycle.jl matters enter-* focus modes, i.e. all but "click". 
It's done by replacing make-timer with a different code. Theoretically both 
should work, but the code with timer doesn't. I can't tell why. (Timer seems to 
be called correctly as far as I investigated.) Anyway Librep's timer works in a 
very esoteric way.

Let me point out one more thing; the news says that `focus-when-mapped' can 
take the value `maybe', but it isn't there. Maybe you can add `default', which 
is self-exeplanatory. Even in that case wm/state/transient.jl can be left 
intact since the case of `default' can be ignored there. (Thus it's equivalent 
to not setting focus-when-mapped.) Thanks for implementing it.

Am i back? Sorry, no. (If you don't know me...ehem, ask Chris or fuchur.) 
Thanks for developing sawfish.

Best regards,
Teika (Teika kazura)

# BTW qtile-0.9 now supports python3. I think it's worth trying, thus installed 
it, but not yet tried; it's because now I've succeeded in fixing the above two 
issues.
>From 221e5f48fc0bb404fc0f10f03b5d824476bdae6b Mon Sep 17 00:00:00 2001
From: Teika kazura <[email protected]>
Date: Fri, 6 Mar 2015 10:43:47 +0900
Subject: [PATCH 2/2] Focus-mode `enter-exit' bugfix; it used to react to
 `pointer-out'. It caused unwanted focus loss.

At least two cases are known. One is when a new instance of gtk's drop down menu appears, and the pointer has been located in the menu's inside area. The other is firefox' urlbar autocompletion; when the cursor lies slightly below the urlbar, and autocompletion appears, it flickers and not few keypresses are lost.

Both were terribly inconvienient.
---
 lisp/sawfish/wm/focus.jl | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lisp/sawfish/wm/focus.jl b/lisp/sawfish/wm/focus.jl
index 3e1ec93..f480c4d 100644
--- a/lisp/sawfish/wm/focus.jl
+++ b/lisp/sawfish/wm/focus.jl
@@ -155,15 +155,15 @@ EVENT-NAME)', where EVENT-NAME may be one of the following symbols:
 ;;; modes
 
   (define-focus-mode 'enter-exit
-    (lambda (w action . args)
+    ;; `pointer-out' should not be caught. `enter-root' handles it.
+    ;; Furthermore, pointer-out used to make troubles: for example,
+    ;; an appearance of a menu by alt-key which covers the pointer
+    ;; made the focus lost.
+    (lambda (w action)
       (case action
 	((pointer-in)
 	 (when (window-really-wants-input-p w)
 	   (set-input-focus w)))
-	((pointer-out)
-	 ;; ignore grab/ungrab leave events
-	 (when (eq (car args) 'normal)
-	   (set-input-focus nil)))
 	((enter-root)
 	 ;; ensure that any desktop window gets focused
 	 (set-input-focus w))
-- 
2.0.4

>From fdb2172a7c19a8c538b457f1dd21f684c3be5e2d Mon Sep 17 00:00:00 2001
From: Teika kazura <[email protected]>
Date: Fri, 6 Mar 2015 10:04:20 +0900
Subject: [PATCH 1/2] Bugfix in x-cycle.jl. Previously the focus change by
 pointer motion was ignored after x-cycle.

This was due to the use of timer; Librep's timer is not a thread, but related to event-loop in an esoteric manner.
---
 lisp/sawfish/wm/commands/x-cycle.jl | 11 ++++++-----
 lisp/sawfish/wm/focus.jl            | 24 +++++++++++++++++-------
 2 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/lisp/sawfish/wm/commands/x-cycle.jl b/lisp/sawfish/wm/commands/x-cycle.jl
index 47c579a..3a48736 100644
--- a/lisp/sawfish/wm/commands/x-cycle.jl
+++ b/lisp/sawfish/wm/commands/x-cycle.jl
@@ -289,15 +289,16 @@
                   (catch 'x-cycle-exit
                     ;; do the first step
                     (cycle-next windows step)
-                    (setq focus-ignore-pointer-events t)
+		    ;; Record current time + 0.1 sec.
+                    (setq focus-xcycle-timestamp
+			  (cons (current-time)
+				(+ 100000 (current-utime))))
+
                     (recursive-edit))
                   (when (fluid x-cycle-current)
                     (display-window (fluid x-cycle-current))))
               (remove-message)
-              (ungrab-keyboard)
-              (make-timer (lambda ()
-                            (setq focus-ignore-pointer-events nil))
-                          0 100)))))
+              (ungrab-keyboard)))))
 
       (when tail-command
 	;; make sure that the command operates on the newly-focused
diff --git a/lisp/sawfish/wm/focus.jl b/lisp/sawfish/wm/focus.jl
index 3ca0886..3e1ec93 100644
--- a/lisp/sawfish/wm/focus.jl
+++ b/lisp/sawfish/wm/focus.jl
@@ -16,7 +16,7 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with sawfish; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 
+;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 ;; Boston, MA 02110-1301 USA.
 
 (define-structure sawfish.wm.focus
@@ -62,10 +62,20 @@
     :type boolean
     :group focus)
 
-
-  ;; Only used by x-cycle.jl
-  (defvar focus-ignore-pointer-events nil
-    "When true, pointer in/out events don't cause focus changes.")
+  (defvar focus-xcycle-timestamp (cons (current-time) (current-utime))
+    ;; current-utime can overflow librep's integer, which is 30-bit if minimal.
+    ;; To be safe, current-time is used, too.
+    "Used only to support x-cycle.jl.")
+
+  (define (ignore-pointer-events)
+    ;; Only necessary to support x-cycle.jl
+    ;; Returns t if current-time is later than focus-xcycle-timestamp
+    (prog1
+	(and focus-xcycle-timestamp
+	     (or (> (current-utime) (cdr focus-xcycle-timestamp))
+		 (time-later-p (current-time) (car focus-xcycle-timestamp))
+		 ))
+      (setq focus-xcycle-timestamp nil)))
 
   (define focus-within-click-event (make-fluid nil)
           "When true, the current command is being called from within
@@ -253,14 +263,14 @@ EVENT-NAME)', where EVENT-NAME may be one of the following symbols:
 ;;; hooks
 
   (define (focus-enter-fun w mode)
-    (unless focus-ignore-pointer-events
+    (unless (ignore-pointer-events)
       (cond ((desktop-window-p w)
 	     (focus-invoke-mode w 'enter-root mode))
 	    ((windowp w)
 	     (focus-invoke-mode w 'pointer-in mode)))))
 
   (define (focus-leave-fun w mode)
-    (unless focus-ignore-pointer-events
+    (unless (ignore-pointer-events)
       (cond ((desktop-window-p w)
 	     (focus-invoke-mode w 'leave-root mode))
 	    ((windowp w)
-- 
2.0.4

Reply via email to