shithub: riow

Download patch

ref: 737ffa63cece7382369c4b8eaaa2906ba3bae259
parent: b6b91c9942420f7d399c1df0742961d4eb12138a
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Aug 29 16:14:55 EDT 2022

Kmod4+h/j/k/l - focus left/down/up/right; re-read label to keep sticky status up to date

--- a/README.md
+++ b/README.md
@@ -13,7 +13,8 @@
  * virtual desktops from 1 to 0
  * switch between desktops
  * move windows between desktops
- * toggle fullscreen on the current window
+ * switch focus between windows
+ * toggle fullscreen mode on the current window
  * start a new window
  * "sticky" programs, by default `stats`, `kbmap` etc are shown on every desktop
  * toggle "sticky" mode for current window
--- a/riow.c
+++ b/riow.c
@@ -112,17 +112,20 @@
 		if(!seen){
 			/* not seen previously - set the new state for it */
 			w->vd = vd;
-			snprint(s, sizeof(s), "/dev/wsys/%d/label", w->id);
-			if((f = open(s, OREAD)) >= 0){
-				n = read(f, s, sizeof(s)-1);
-				close(f);
-				if(n > 0){
-					s[n] = 0;
-					for(k = 0; k < nelem(sticky) && sticky[k] != nil; k++){
-						if(strcmp(sticky[k], s) == 0){
-							w->flags |= Fsticky;
-							break;
-						}
+		}
+
+		/* because a different program can run in any window we have to re-read */
+		snprint(s, sizeof(s), "/dev/wsys/%d/label", w->id);
+		w->flags &= ~Fsticky;
+		if((f = open(s, OREAD)) >= 0){
+			n = read(f, s, sizeof(s)-1);
+			close(f);
+			if(n > 0){
+				s[n] = 0;
+				for(k = 0; k < nelem(sticky) && sticky[k] != nil; k++){
+					if(strcmp(sticky[k], s) == 0){
+						w->flags |= Fsticky;
+						break;
 					}
 				}
 			}
@@ -235,7 +238,53 @@
 	close(f);
 }
 
+static struct {
+	int x, y;
+}cyclectx;
+
+static int
+cyclecmp(void *a_, void *b_)
+{
+	W *a = a_, *b = b_;
+
+	return cyclectx.x*(a->r.min.x - b->r.min.x) + cyclectx.y*(a->r.min.y - b->r.min.y);
+}
+
 static void
+cycleaction(int x, int y)
+{
+	int wcurid, i, f;
+	W *w, *w₀;
+
+	wcurid = wcur == nil ? -1 : wcur->id;
+	cyclectx.x = x;
+	cyclectx.y = y;
+	qsort(ws, wsn, sizeof(*ws), cyclecmp);
+	w₀ = nil;
+	wcur = nil;
+	for(i = 0, w = ws; i < wsn; i++, w++){
+		if(w->id == wcurid){
+			wcur = w;
+			continue;
+		}
+		if((w->flags & Fsticky) != 0 || w->vd != vd)
+			continue;
+		if(w₀ == nil)
+			w₀ = w;
+		if(wcur != nil)
+			break;
+	}
+	if(i >= wsn)
+		w = w₀;
+	if(w == nil || (f = wwctl(w->id, OWRITE)) < 0)
+		return;
+	fprint(f, "top");
+	fprint(f, "current");
+	close(f);
+	wcur = w;
+}
+
+static void
 keyevent(Rune r)
 {
 	wsupdate();
@@ -256,6 +305,14 @@
 		arrowaction(-1, 0);
 	else if(r == Kright)
 		arrowaction(1, 0);
+	else if(r == 'h')
+		cycleaction(-1, 0);
+	else if(r == 'l')
+		cycleaction(1, 0);
+	else if(r == 'j')
+		cycleaction(0, 1);
+	else if(r == 'k')
+		cycleaction(0, -1);
 }
 
 static void
--- a/riow.man
+++ b/riow.man
@@ -58,6 +58,9 @@
 Spawn a new
 .IR window(1) .
 .TP
+.B Kmod4+h/j/k/l
+Focus left/down/up/right.
+.TP
 .B Kmod4+arrows
 Move the current window in the specified direction.
 .TP