bspwm icon indicating copy to clipboard operation
bspwm copied to clipboard

Google Chrome / Electron apps don't "unfocus" when changing desktop

Open drasill opened this issue 6 years ago • 86 comments

Hi,

when focusing a window, if the previous window is Chrome, it doesn't "unfocus", if they are not both on the same desktop.

Exemple :

  • with bspc node -f older (called from sxhkdrc)
  • if I go from a google chrome window to, say, a terminal on another desktop
  • the chrome window still believes it's focused.

I did confirm it by typing this in the DevTools of any chrome window :

setInterval( function(){ console.log( document.hasFocus()); }, 500 );

✔ The "focus" goes from true to false when I focus another window on the same desktop. ✘ The "focus" keeps being true when I focus another window on another desktop.

This doesn't happen with firefox. I suppose Chrome doesn't have the same method to check it's focused state.

It's a real problem for some Electron applications (like discord), which notifies you when focus is lost. In this case, changing desktop doesn't show notifications.

Thank you for reading :)

drasill avatar May 31 '18 12:05 drasill

Another bump! Would love to know if any progress has been made, and what we can do about it!

ar1a avatar Jun 22 '19 13:06 ar1a

A third bump, this is causing problems for me with notifications as well -- happy to look into it if I know whether Electron or BSPWM are in the wrong.

m3rcuriel avatar Sep 05 '19 03:09 m3rcuriel

Also, switching to a desktop, which has a float window in it, produces the same bug.

But, it does not bug if the mouse cursors is on the window after the switch; the electron window is correctlyunfocused.

A first I though it was because of having focus_follows_pointer=true, but even with this option set to false, the behavior does not change.

I think BSPWM is in the wrong, since the bug differs based on where we are focusing.

drasill avatar Nov 25 '19 15:11 drasill

I too face this issue, and it's very annoying. For me, the issue is with discord notifications - I don't get notifications of the focused channel if I change workspaces normally with discord in focus in that workspace. My workarounds are focusing a different window before changing workspaces, or going to the Friends tab so I get notifications.

I found this reddit post from 5 months ago, whose OP had the exact same issue as me. They've found this interesting thing:

I found something strange. If I switch desktop by using the keyboard shortcut, the notification does not work. But if I switch desktop by using the mouse click on polybar, the notification works. Maybe polybar use different commands to switching desktop ?

And they've also come up with a workaround to the normal workspace-switching command.

Why hasn't there been any progress in this issue for nearly 2 years now?

cubetastic33 avatar Jan 16 '20 07:01 cubetastic33

Ok, the workaround @cubetastic33 mentioned is working great, although it is ugly as hell.

I've replaced all bspc node -d or bspc desktop -f by calls to a script :

#!/bin/sh
eval "$(xdotool getmouselocation --shell)"
xdotool mousemove 960 1080
if [ "$2" = "move" ]; then
	bspc node -d "$1"
elif [ "$2" = "follow" ]; then
	bspc node -d "$1" -f
else
	bspc desktop -f "$1"
fi
xdotool mousemove --screen $SCREEN $X $Y

drasill avatar Jan 16 '20 11:01 drasill

Indeed. Why can't we fix this in bspwm's source code?

cubetastic33 avatar Jan 16 '20 11:01 cubetastic33

@baskerville Any ideas what could be going wrong? Unfortunately all the most popular communication apps are Electron-based and thus all their messaging notifications are affected.

mixedCase avatar Feb 21 '20 15:02 mixedCase

I do experience the same, subscribed.

dakyskye avatar May 14 '20 13:05 dakyskye

@baskerville I'm facing the same thing, with Slack, Discord, etc. I would be happy to look at this if you could point me in the right direction.

instantepiphany avatar Aug 03 '20 03:08 instantepiphany

Ok, the workaround @cubetastic33 mentioned is working great, although it is ugly as hell.

I've replaced all bspc node -d or bspc desktop -f by calls to a script :

#!/bin/sh
eval "$(xdotool getmouselocation --shell)"
xdotool mousemove 960 1080
if [ "$2" = "move" ]; then
	bspc node -d "$1"
elif [ "$2" = "follow" ]; then
	bspc node -d "$1" -f
else
	bspc desktop -f "$1"
fi
xdotool mousemove --screen $SCREEN $X $Y

I've done some reading and testing. I can reliably reproduce this issue. If I have slack open on a desktop, and switch to another desktop using the default sxhkd keyboard shortcut, slack does not send a notification to ewmh. Slack even marks the message as read.

However, if I move my mouse so it is not hovering over the slack window, and then use the keyboard shortcut to change desktops, I correctly get the notification.

My suspicion is that at some point when switching desktops, either 1. slack checks the mouse position or 2. bspwm does.

I haven't tested this with Discord (don't have a good way to do that), but I suspect it would show the same behaviour.

This explains why the above workaround fixes the problem - the mouse is moved away from the slack window before switching desktops.

I'm still digging through bspwm's code to see if the issue is bspwm, or electron.

instantepiphany avatar Aug 03 '20 08:08 instantepiphany

The X.Org events can be recorded.

baskerville avatar Aug 03 '20 08:08 baskerville

I think the issue is likely with bspwm, because this issue doesn't happen with other WMs like i3, for example. And I've been facing this issue for so long that I always move my mouse outside discord from muscle memory :joy: It would be really cool if this issue were fixed

cubetastic33 avatar Aug 03 '20 08:08 cubetastic33

@instantepiphany do you have focus_follows_pointer or pointer_follows_focus set in bspwmrc?

baskerville avatar Aug 03 '20 08:08 baskerville

@baskerville no, just the example config: image

instantepiphany avatar Aug 03 '20 08:08 instantepiphany

And the behaviour I described above isn't affected by whether slack is focused or not - I tried opening a terminal window beside it and the only variable that changed whether or not I got the notification was if my mouse was inside the slack window when I switched desktops.

For example, with only the slack window open, if I move my mouse to the gaps so it isn't inside the window, then switch desktops and trigger a notification, I receive it correctly.

instantepiphany avatar Aug 03 '20 08:08 instantepiphany

I have windows I can't close, so I can't test this right now, but I wonder if we need to inform ewmh of an active window change? image

Edit:

Actually, if the above were the case, I would be able to see that in xprop, which I can't. xprop shows everything set correctly (_ACTIVE_WINDOW is 0x0 once the desktop is switched).

If this really doesn't happen in i3, I wonder if i3 has a workaround inbuilt to force apps to believe they aren't active/focused anymore.

instantepiphany avatar Aug 03 '20 08:08 instantepiphany

I made this simple electron program to reproduce this bug with:

index.js:

const { exec } = require("child_process");
const { app, BrowserWindow } = require("electron");

app.whenReady().then(function() {
    const win = new BrowserWindow();
    win.loadURL("https://github.com/baskerville/bspwm/issues/811");
});

app.on("browser-window-focus", function(e, win) {
    console.log("hello");
    exec("notify-send hello").unref();
});
app.on("browser-window-blur", function(e, win) {
    console.log("bye");
    exec("notify-send bye").unref();
});

package.json:

{
  "name": "electron-temp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron ."
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "child_process": "^1.0.2",
    "electron": "^9.1.2"
  }
}

Put these two files in a directory and then run npm install.

To launch the program, run npm start.

With this program, it's very easy to reproduce (especially for me since I don't use discord or slack).

emanuele6 avatar Aug 03 '20 08:08 emanuele6

https://github.com/baskerville/bspwm/issues/811#issuecomment-667889182

@instantepiphany, I tried to use that patch and the problem wasn't fixed.

emanuele6 avatar Aug 03 '20 08:08 emanuele6

@baskerville, that commit didn't fix the issue.

emanuele6 avatar Aug 03 '20 11:08 emanuele6

@baskerville https://youtu.be/Xy9TLXJmL54

emanuele6 avatar Aug 03 '20 11:08 emanuele6

@emanuele6 I've used your test case: the script previously didn't print bye when switching desktops and now it does.

Am I missing something?

baskerville avatar Aug 03 '20 11:08 baskerville

@emanuele6 I've used your test case: the script previously didn't print bye when switching desktops and now it does.

Am I missing something?

The issue is that it only prints bye when you switch desktops while the pointer isn't hovering the window. It doesn't print bye if you switch desktop while the pointer is hovering the window. (← issue)

emanuele6 avatar Aug 03 '20 11:08 emanuele6

@emanuele6 I've used your test case: the script previously didn't print bye when switching desktops and now it does.

No, before d4dee39, it also printed bye if you changed desktop while the pointer wasn't hovering the window.

d4dee39 didn't change the behaviour of the electron program. It seems that d4dee39 didn't accomplish anything.

emanuele6 avatar Aug 03 '20 12:08 emanuele6

@emanuele6 You're right: in fact I think the electron window really wants a LeaveNotify event. So if you have a floating window in another desktop, and your pointer is inside this window, you can leave the pointer inside the electron window, and when the desktop is switched, your test script will print bye!

baskerville avatar Aug 03 '20 12:08 baskerville

@baskerville So does that mean LeaveNotify are currently not sent to a window if that window has the cursor over it and you switch to an empty desktop? And the fix would then be to send this event in that case.

instantepiphany avatar Aug 05 '20 05:08 instantepiphany

I just saw that the case was opened on May 31, 2018 that is now 2 years and no progress in sight ?

kristoferus75 avatar Aug 15 '20 07:08 kristoferus75

Hi !

I dont know if this help :

in herbstluftwm -> the chrome browser no reaction until my claws-mail is opened and i need manualy close it -> badly that on bspwm :-)

in spectrwm -> no problem it works -> no issue !

my issue: https://github.com/baskerville/bspwm/issues/1174

regards kristoferus75

kristoferus75 avatar Aug 15 '20 10:08 kristoferus75

I've noticed that both spectrwm and i3 pass the timestamp of the last received event as the last argument to xcb_set_input_focus while bspwm passes XCB_CURRENT_TIME.

baskerville avatar Aug 15 '20 18:08 baskerville

I've noticed that both spectrwm and i3 pass the timestamp of the last received event as the last argument to xcb_set_input_focus while bspwm passes XCB_CURRENT_TIME.

I tried to use this patch, but it didn't solve the problem:

diff --git a/src/events.c b/src/events.c
index 3b82c96..8ff6919 100644
--- a/src/events.c
+++ b/src/events.c
@@ -36,6 +36,7 @@
 #include "events.h"
 
 uint8_t randr_base;
+xcb_timestamp_t last_event_timestamp = 0;
 
 void handle_event(xcb_generic_event_t *evt)
 {
@@ -86,6 +87,7 @@ void handle_event(xcb_generic_event_t *evt)
 			}
 			break;
 	}
+	last_event_timestamp = XCB_CURRENT_TIME;
 }
 
 void map_request(xcb_generic_event_t *evt)
diff --git a/src/events.h b/src/events.h
index f144dcc..1c4bdc1 100644
--- a/src/events.h
+++ b/src/events.h
@@ -31,6 +31,7 @@
 #define ERROR_CODE_BAD_WINDOW  3
 
 extern uint8_t randr_base;
+extern xcb_timestamp_t last_event_timestamp;
 static const xcb_button_index_t BUTTONS[] = {XCB_BUTTON_INDEX_1, XCB_BUTTON_INDEX_2, XCB_BUTTON_INDEX_3};
 
 void handle_event(xcb_generic_event_t *evt);
diff --git a/src/window.c b/src/window.c
index cd2340d..83b523a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -29,6 +29,7 @@
 #include <xcb/shape.h>
 #include "bspwm.h"
 #include "ewmh.h"
+#include "events.h"
 #include "monitor.h"
 #include "desktop.h"
 #include "query.h"
@@ -928,7 +929,7 @@ void set_input_focus(node_t *n)
 		clear_input_focus();
 	} else {
 		if (n->client->icccm_props.input_hint) {
-			xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, n->id, XCB_CURRENT_TIME);
+			xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, n->id, last_event_timestamp);
 		} else if (n->client->icccm_props.take_focus) {
 			send_client_message(n->id, ewmh->WM_PROTOCOLS, WM_TAKE_FOCUS);
  		}

NOTE: adding last_event_timestamp = XCB_CURRENT_TIME; before the switch block instead of after the switch block doesn't solve this either.

emanuele6 avatar Aug 15 '20 19:08 emanuele6

@emanuele6 last_event_timestamp = XCB_CURRENT_TIME is not going to help, what we want is last_event_timestamp = e->time in each event handler…

baskerville avatar Aug 15 '20 19:08 baskerville

Oh, sorry about that, I don't have much experience at all with libxcb.

what we want is last_event_timestamp = e->time in each event handler…

It doesn't look like event types have a time field (or any field of type xcb_timestamp_t) though, example:

typedef struct xcb_map_request_event_t {
    uint8_t      response_type;
    uint8_t      pad0;
    uint16_t     sequence;
    xcb_window_t parent;
    xcb_window_t window;
} xcb_map_request_event_t;

Maybe there is a function to call to get the timestamp out of an event?

emanuele6 avatar Aug 15 '20 20:08 emanuele6

Some of the events do have a time field, for example xcb_enter_notify_event_t.

baskerville avatar Aug 16 '20 09:08 baskerville

Applying this patch changes the behaviour a little, but it's a bit random (maybe that's just because this is a random change...): https://youtu.be/RUmV8NxWUT8 .

The window behaves like usual, but, if you focus a different desktop and then go back, the window starts getting "focus" and "blur" events also when the pointer enters/exits the window; then, if you switch to another window with a keybind, the window keeps having that behaviour even though it's not focused, but as soon as you refocus it with the mouse, it behaves like usual again. Also, the cursor on my urxvt window looked as if the window wasn't focused even though it was focused when the test window was in that weird state.

diff --git a/src/events.c b/src/events.c
index 3b82c96..1f3b8a3 100644
--- a/src/events.c
+++ b/src/events.c
@@ -36,6 +36,7 @@
 #include "events.h"
 
 uint8_t randr_base;
+xcb_timestamp_t last_event_timestamp = 0;
 
 void handle_event(xcb_generic_event_t *evt)
 {
@@ -364,6 +365,8 @@ void focus_in(xcb_generic_event_t *evt)
 void button_press(xcb_generic_event_t *evt)
 {
 	xcb_button_press_event_t *e = (xcb_button_press_event_t *) evt;
+	last_event_timestamp = e->time;
+
 	bool replay = false;
 	for (unsigned int i = 0; i < LENGTH(BUTTONS); i++) {
 		if (e->detail != BUTTONS[i]) {
@@ -389,6 +392,8 @@ void button_press(xcb_generic_event_t *evt)
 void enter_notify(xcb_generic_event_t *evt)
 {
 	xcb_enter_notify_event_t *e = (xcb_enter_notify_event_t *) evt;
+	last_event_timestamp = e->time;
+
 	xcb_window_t win = e->event;
 
 	if (e->mode != XCB_NOTIFY_MODE_NORMAL || e->detail == XCB_NOTIFY_DETAIL_INFERIOR) {
@@ -414,6 +419,7 @@ void enter_notify(xcb_generic_event_t *evt)
 void motion_notify(xcb_generic_event_t *evt)
 {
 	xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t *) evt;
+	last_event_timestamp = e->time;
 
 	static uint16_t last_motion_x = 0, last_motion_y = 0;
 	static xcb_timestamp_t last_motion_time = 0;
diff --git a/src/events.h b/src/events.h
index f144dcc..1c4bdc1 100644
--- a/src/events.h
+++ b/src/events.h
@@ -31,6 +31,7 @@
 #define ERROR_CODE_BAD_WINDOW  3
 
 extern uint8_t randr_base;
+extern xcb_timestamp_t last_event_timestamp;
 static const xcb_button_index_t BUTTONS[] = {XCB_BUTTON_INDEX_1, XCB_BUTTON_INDEX_2, XCB_BUTTON_INDEX_3};
 
 void handle_event(xcb_generic_event_t *evt);
diff --git a/src/window.c b/src/window.c
index cd2340d..83b523a 100644
--- a/src/window.c
+++ b/src/window.c
@@ -29,6 +29,7 @@
 #include <xcb/shape.h>
 #include "bspwm.h"
 #include "ewmh.h"
+#include "events.h"
 #include "monitor.h"
 #include "desktop.h"
 #include "query.h"
@@ -928,7 +929,7 @@ void set_input_focus(node_t *n)
 		clear_input_focus();
 	} else {
 		if (n->client->icccm_props.input_hint) {
-			xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, n->id, XCB_CURRENT_TIME);
+			xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_PARENT, n->id, last_event_timestamp);
 		} else if (n->client->icccm_props.take_focus) {
 			send_client_message(n->id, ewmh->WM_PROTOCOLS, WM_TAKE_FOCUS);
 		}

For reference, this is the keybind I used in the video (super + g) to focus to the urxvt window:

# Focus a floating window / Cycle floating windows.
super + {_,shift + }g
	bspc node 'focused.floating#{next,prev}.local.!hidden.floating' -f \
	    || bspc node 'last.local.!hidden.floating' -f \
	    || bspc node  'any.local.!hidden.floating' -f

emanuele6 avatar Aug 16 '20 09:08 emanuele6

on dwm the same bug -> if i open dmenu on same workspace on which is the browser -> submenu not work :-(

kristoferus75 avatar Aug 17 '20 11:08 kristoferus75

It also happens with visual code :-(

I have now also open a issue on chromium bug site:

https://bugs.chromium.org/p/chromium/issues/detail?id=1117555

kristoferus75 avatar Aug 18 '20 16:08 kristoferus75

It might be worth noting that i3 and spectrwm are reparenting WMs while bspwm and herbstluftwm aren't.

baskerville avatar Aug 19 '20 14:08 baskerville

the same problem also on opera browser !

kristoferus75 avatar Aug 27 '20 19:08 kristoferus75

Just stumbled across this issue as well. For me the slack electron app is the most notable effect.

Is there any development being done towards solving this? @baskerville , it seemed like you had a fairly good idea of what needs to happen (send NOTIFY_LEAVE event)? Or was that just the root cause of the issue, not a way towards solving this?

I am pretty much clueless regarding any of this, but happy to help in any way I can towards a solution ...

soenkeliebau avatar Sep 18 '20 13:09 soenkeliebau

This makes bspwm completely unusable for me and I guess a lot others... dwm doesn't have this issue at all, maybe steal their code? lol Really unfortunate this hasn't been fixed yet

josefandersson avatar Sep 22 '20 01:09 josefandersson

@baskerville Changing window.c:905 from set_window_state(win, XCB_ICCCM_WM_STATE_ICONIC); to set_window_state(win, XCB_ICCCM_WM_STATE_WITHDRAWN); sort of fixes the issue for me, but not when the destination desktop is empty (no nodes).

Any reason XCB_ICCCM_WM_STATE_ICONIC was used instead of XCB_ICCCM_WM_STATE_WITHDRAWN? Any clue on why window.c:905 doesn't seem to be called when the destination desktop is empty?

josefandersson avatar Sep 22 '20 12:09 josefandersson

~~Could it be that xcb_change_window_attributes(dpy, root, XCB_CW_EVENT_MASK, values_off); is not called whenever the destination desktop is empty? ie [email protected]:688 just returns because n is null (assuming it's null since d->root of an empty desktop is null right?)~~

Nvm it is being called through tree.c:629 -> desktop.c:519 -> tree.c:677 -> window.c:912

josefandersson avatar Sep 22 '20 21:09 josefandersson

This makes bspwm completely unusable for me and I guess a lot others... dwm doesn't have this issue at all, maybe steal their code? lol Really unfortunate this hasn't been fixed yet

It's not that easy: dwm is written with libX11 while bspwm is written with libxcb.

emanuele6 avatar Sep 23 '20 23:09 emanuele6

(Useless comment) I'm struggling with this bug for 2 years now, I'm very happy that you guys are looking into it. Thank you.

drasill avatar Sep 24 '20 06:09 drasill

It's not that easy: dwm is written with libX11 while bspwm is written with libxcb.

Changing XCB_ICCCM_WM_STATE_ICONIC to XCB_ICCCM_WM_STATE_WITHDRAWN I got from dwm though (not the same macro name bcs different lib but they passed 0 while bspwm passed 2), in the end they still run on xorg

Don't know why bspwm passes 2 normally but changing it to 0 pretty much fixes it for me so that's the build I'm gonna run and I hope my two questions get answered

@drasill It's such a stupid bug for an otherwise great wm, it really is a shame... I'd recommend cloning the git and changing what I said in the previous post, compile and run that build

josefandersson avatar Sep 24 '20 16:09 josefandersson

You are right, this is working great... when the destination is not empty.

It doesn't work neither when going to an empty desktop and then to a non-empty one, focusing any window; and this happen fairly often.

Great work though, it's a nice start.

drasill avatar Sep 25 '20 07:09 drasill

@drasill Yeah it's not perfect but an improvement. I usually populate my desktops in a swoop during startup so it's very seldom I go to an empty desktop, so for me I haven't actually had it be a problem yet. It feels like I've gone followed the stack five times around now and it still looks like it should all work properly, but nope......

edit: The fix doesn't seem to work for destination desktops with some specific applications running in it, for example if the target desktop only contains one IntelliJ window then the previously focused window won't be unfocused like before. This makes me think whether the source app is unfocused is dependent on the target application in some way handling/acknowledging the focus event? I really would need to pick up a book on xorg to solve this, anyone got any recommendations lol

josefandersson avatar Sep 25 '20 13:09 josefandersson

Hi @baskerville , did you have a chance to check out the fix proposed by @josefandersson yes? If this really works it would be great to get this merged, so we don't need to run of a fork of bspwm.

soenkeliebau avatar Oct 05 '20 13:10 soenkeliebau

@josefandersson just came back to check progress on this issue and actually really read your last comment for the first time. Intellij is a problem child for bspwm anyway - or at least has been for me. Half the time when switching to intellij it doesn't focus properly (for lack of a better word), it does get seem to get the focus, but never shows a cursor and I cannot type. In earlier versions (not sure of what) this was fixable, or at least improveable by setting suppress.focus.stealing=false in the Intellij settings, but as of some time ago this seems to not be effective anymore.

soenkeliebau avatar Nov 03 '20 15:11 soenkeliebau

@soenkeliebau Really? And it works fine on other WMs? Only problem with IntelliJ for me when running bspwm on Arch is the focus thing in my last comment. The fix I am using rn (and have been since my last comment) is that I have create a small window with xorg library in c and make it floaty and position it outside of the screen and whenever I change desktop (super+num) I move that window first, then switch desktop, then push the floaty window to the bottom the stack aka focus the application on the new desktop. This makes the focus issue completely go away and it is pretty much seamless except for a small flicker in polybar between when the floaty window is sent to the other desktop and the desktop change happens. Wouldn't recommend it, but it works for me. I'll probably leave bspwm behind before this is properly fixed so I'll just roll with this and not spend more time on it.

josefandersson avatar Nov 03 '20 19:11 josefandersson

@josefandersson I've never really tried it on other wm's to be honest. I have not yet managed to adopt a "mostly keyboard" workflow" I'm sad to say, so it doesn't bother me overly much.

In my opinion that's way of doing things when running linux as desktop os - sure, you can fix everything somehow, but 95% are just not worth the trouble and you just learn to ignore it. You either become a bit stoic about these things or move on to MacOS :)

soenkeliebau avatar Nov 04 '20 09:11 soenkeliebau

@baskerville @soenkeliebau This 2-year old issue seems to be bothering several users, so as a little incentive, I'm rewarding a $200 bounty to the person providing a fix that can be merged to master.

This patch is a good start, however, as others have pointed out, it is not a full solution. For example, it doesn't work in empty desktops or when the focus changes to Java (and maybe other) applications.

I encourage others to increase the "reward pool" in order to bring more attention to this annoying issue.

Thanks!

r-31415 avatar Dec 16 '20 21:12 r-31415

Hi @rsmith31415 that is good news, happy to pitch in a few buck as well! Can you point me towards where you created the reward pool?

soenkeliebau avatar Dec 16 '20 21:12 soenkeliebau

Hi @soenkeliebau I was told in #bspwm (IRC) that it was possible to offer the reward as a comment. I'm happy to use a more formal alternative if that's needed (maybe Bountysource?)

r-31415 avatar Dec 16 '20 22:12 r-31415

I'd pitch in $20 USD.

lfrancke avatar Dec 17 '20 12:12 lfrancke

I'll pitch in 30 USD, that brings us to 250 overall I believe.

soenkeliebau avatar Dec 17 '20 12:12 soenkeliebau

That's cool of you guys. Spent another few hours looking at it today but still can't wrap my head around what's missing. To me it looks like everything that interacts with the previously focused window runs exactly the same no matter if the destination desktop is empty or not. 😭 I'll continue later this evening if I can find the motivation...

josefandersson avatar Dec 17 '20 15:12 josefandersson

linking a heavyhanded attempted script workaround that works for me in the Chrome console logging case (I couldn't repro Discord). I have the following in an electron_fix script that runs on it's own with no args:

#!/usr/bin/env bash

get_class_wids() {
    for wid in ${!wid_to_class[@]}; do
	if grep -qi "$*" <<< "${wid_to_class[$wid]}" ; then
	    echo "$wid"
	fi
    done
}

set_state() {
    for wid in $(get_class_wids "$*"); do
	# if wid is not in our dtop, hide it (attempt to force unfocus)
	if bspc query -N -d .focused -n $wid >/dev/null; then
	    echo "$*: showing!"
	    bspc node $wid -g hidden=false
	else
	    echo "$*: hiding!"
	    bspc node $wid -g hidden=true
	fi
    done
}

declare -A wid_to_class=();
act() {
    # cache
    wid_to_class=();
    for wid in $(bspc query -N -n .window); do
	wid_to_class[$wid]=$(xprop WM_CLASS -id "$wid")
    done

    # NB: add cases here:
    set_state google-chrome
    set_state discord
}

act

while read -r event mon_id desk_id; do
    act

    # fix refocus issue by using xqp: https://github.com/baskerville/xqp
    # if $(bspc config focus_follows_pointer); then
    # 	bspc node -f $(xqp)
    # fi
done < <(bspc subscribe desktop_focus)

(disclaimer: not looking for the bounty, would appreciate if someone affected by this issue more thoroughly than myself could test this)

neeasade avatar Dec 23 '20 21:12 neeasade

I can confirm that @neeasade's script works for me on Discord.

EDIT: After using it for a bit of time, I notice a few caveats:

  • Once the node is hidden, clicking notifications do not take me to the window.
  • If there is more than one window on the desktop, it is quite jarring when switching to the desktop as the windows quickly resize themselves.

radiantly avatar Feb 02 '21 08:02 radiantly

@josefandersson and any others who maybe spends time to try and fix this; I have this bug on the Slack desktop app but not on the Signal desktop app (which I believe is also an Electron app?). Maybe there can be a hint in the code for the Signal app to see what is done differently?

blaklinten avatar Feb 08 '21 09:02 blaklinten

@blaklinten curious. I have it on Signal but it looks like Signal has its own "is active" detection which might come into play. Do you have the problem with or without the WITHDRAWN patch?

m3rcuriel avatar Feb 08 '21 18:02 m3rcuriel

I got the bug both with the patch as well as without it.

If Slack is alone on a workspace, it will not unfocus when I switch workspace. It does not matter what desktop I switch to, weather it is empty or populated. However, if Slack has another window, say a terminal on the same workspace I can switch workspace as expected. This is not the case with Signal; I can always switch away from a workspace with Signal app on, weather Signal is the only window or not and it works as expected.

I also noticed some intense flickering when moving the cursor around if Slack is alone on a workspace. This is made worse when running a compositor; if compton is running Slack does not render any changes to the window at all. I dont know if this might be reelvant...

blaklinten avatar Feb 09 '21 13:02 blaklinten

I have applied the patch and I experience the empty desktop issue with Discord.

alexacallmebaka avatar Feb 14 '21 06:02 alexacallmebaka

Any solutions? almost all comm apps are now electron-based. And this a big issue, especially Work From Home situation.

rjshrjndrn avatar Mar 17 '21 20:03 rjshrjndrn

Any solutions? almost all comm apps are now electron-based. And this a big issue, especially Work From Home situation.

I'm still using my patch + some scripting to fix it, so I haven't even thought about the bug since December, but I'm not very hopeful of a real fix ever tbh, it's been almost 3 years

josefandersson avatar Mar 17 '21 20:03 josefandersson

I'm not super savvy on bspwm. WIll try out other wms. After all WMs are basic need, which we'll have to depend on. The only sad thing is I was pretty happy with bspwm. :(

rjshrjndrn avatar Mar 17 '21 21:03 rjshrjndrn

Ok, the workaround @cubetastic33 mentioned is working great, although it is ugly as hell.

I've replaced all bspc node -d or bspc desktop -f by calls to a script :

#!/bin/sh
eval "$(xdotool getmouselocation --shell)"
xdotool mousemove 960 1080
if [ "$2" = "move" ]; then
	bspc node -d "$1"
elif [ "$2" = "follow" ]; then
	bspc node -d "$1" -f
else
	bspc desktop -f "$1"
fi
xdotool mousemove --screen $SCREEN $X $Y

This script works really well and fixes the issue in almost all cases, the only place where I have a problem is when the desktop is changed through an EWMH signal, or by clicking a link which opens it in the browser, which is on a different desktop. But these scenarios are pretty rare, and for the vast majority of cases, the script fixes it. You'll notice the cursor jump for a split second, but that's better than having to deal with the notification issue, imo. It is, of course, just a dirty workaround, but I thought I'd bring this up again in case you guys didn't notice it due to it being such an old comment.

Note: I modified the mousemove line to xdotool mousemove 0 5, so that it would also work on monocle mode (which I use with no margins). The y coordinate is 5 so that firefox doesn't try to show the tab bar when it's fullscreened, which would happen if you use 0.

cubetastic33 avatar Mar 18 '21 02:03 cubetastic33

@cubetastic33 never been a fan of the mousemove "solution", they are quite frankly ridiculous since it looks awful and also jerks the pointer around. I may not have shared this in the thread but this is what I've used for the past half a year (in addition to set_window_state(win, XCB_ICCCM_WM_STATE_WITHDRAWN); in window.c:905): https://gist.github.com/josefandersson/f26ed70fdddd5f508352f34d0911809d

I create a 'ghost window' at start and then send that to the other desktop before I switch. Only problem I've got is that it is possible to terminate the ghost window so some scripts will have to adapt to that—or just reload bspwm if it ever happens.

josefandersson avatar Mar 18 '21 09:03 josefandersson

I'd definitely love it if I could use a better solution or even workaround than the mouse move one! With your ghost window method though, won't there always be an extra window in the desktop when I'm cycling through the windows (bspc node -f next.local.window)?

Also, I just properly read the earlier comments about IntelliJ, and I've never had focus problems with it - although whenever I have a fresh install of bspwm, intellij won't work and I need to add this environment variable for it to work: _JAVA_AWT_WM_NONREPARENTING=1

cubetastic33 avatar Mar 18 '21 09:03 cubetastic33

I'd definitely love it if I could use a better solution or even workaround than the mouse move one! With your ghost window method though, won't there always be an extra window in the desktop when I'm cycling through the windows (bspc node -f next.local.window)?

Also, I just properly read the earlier comments about IntelliJ, and I've never had focus problems with it - although whenever I have a fresh install of bspwm, intellij won't work and I need to add this environment variable for it to work: _JAVA_AWT_WM_NONREPARENTING=1

I never use next.local.window so I don't know. Never had any focusing issues with the sxhkd config I use at least.

I don't recall what IntelliJ problem I was having (also with that env var) but whatever it was it hasn't been an issue for me since I started using my workaround above.

josefandersson avatar Mar 18 '21 09:03 josefandersson

@baskerville Any plans to fix this? Still an issue.

jjc224 avatar Feb 06 '22 01:02 jjc224

I was using qtile last few months and wanted to migrate to bspwm but this issue is a real deal-breaker. 😥

uguremirmustafa avatar Apr 14 '22 14:04 uguremirmustafa

For what it is worth, given the lack of activity in this issue, I migrated to dwm a few months ago. If you are really bothered by this sort of bug, I think you might give other WMs a try.

r-31415 avatar Apr 14 '22 21:04 r-31415

On the topic of Electron based programs and window managers, I've found this to be a nagging issue across the spectrum, no matter what WM I use. It's definitely electron, for me, maybe others.

corpsouth avatar Apr 15 '22 02:04 corpsouth

@CorpSouth which ones? i3, qtile, dwm? As far as I can tell, dwm 6.2 doesn't suffer from the same issues. If I remember correctly, qtile didn't have this particular issue either but there were visual artifacts running Android Studio.

r-31415 avatar Apr 15 '22 02:04 r-31415

@rsmith31415 sure, here are a few examples:

bspwm: this issue with discord at hand dwm: 6.3, I've had discord occasionally disappear when restarting in-place (months ago, possibly an old bug with discord) enhanced motif window manager: refuses to let me resize discord i3: in regular windows the focus refuses to cycle with focus next/prev commands, in stacks or tabs it lets me cycle focus

This is what lead me to believe it was the error of Electron apps, not the window manager itself.

corpsouth avatar Apr 15 '22 02:04 corpsouth

@CorpSouth That's fair, but you're referencing slightly different issues under different conditions (focus changing vs resizing vs window disappearing vs focus when cycling only in certain layouts). It may very well be the case that all of them are related, but I don't think different behaviors for each WM points to the same underlying root cause in Electron apps.

r-31415 avatar Apr 15 '22 07:04 r-31415

Right now my solution is just to use the web versions of Discord, Slack, etc., which has pros and cons but is a viable workaround for this issue. The hacks didn't work for me and aren't very palatable.

I definitely experienced the same kind of focus/notification issue on dwm in the past. I can't speak for the latest version though.

I'm not opposed to using other WMs (in fact, I've been considering switching back to dwm just because of glitches in bspwm in general and zero support). But I'm a long-time dwm user and wanted something new that's decent. I disagree with some design choices in i3, it's basically unusable for me, though it does a lot of things right. I've tried most WMs.

It is a shame because bspwm has potential. Perhaps someone will maintain a decent fork in the future.

jjc224 avatar Apr 22 '22 07:04 jjc224

~~I've installed arch and I installed bspwm, this issue seems to be solved, why is it working has it been solved?~~ Nevermind it was cause I had it closed into the tray

ThatOneOcto avatar Jun 08 '22 21:06 ThatOneOcto

The only obvious "solution" is to switch window managers, you should check out qtile and xmonad if you like WMs that you only get a wm and you add your own bar, qtile has it's own bar though but it's very good and it's written entirely in python so the syntax is easy

It's been 4 years I don't think this will be solved anytime soon

ThatOneOcto avatar Jun 10 '22 21:06 ThatOneOcto