I noticed some annoying behaviour with vlc playing movies in
fullscreen mode, and I think we're at fault rather than the
application in this case.
What happens is that vlc goes to fullscreen mode but doesn't gain
focus, which means keyboard shortcuts don't work unless you first
switch to the fullscreen window.
To reproduce:
* Launch vlc and configure it to switch to fullscreen when playing
a movie and to disallow multiple instances.
* Switch to a terminal and type 'vlc /media/funny_cats.mp4' or use
a file manager to open funny_cats.mp4 with vlc.
* Press space to pause the movie. Nothing happens because the
terminal/file manager still has focus.
Note that the bug doesn't manifest itself if vlc wasn't already
running. In that case it would launch, thus gaining focus, and retain
focus after switching to fullscreen. Similarly if you used the
builtin file browser to choose the movie you wanted to watch it would
work because the application had focus going into fullscreen.
The patch is very simple. We keep track of which window had focus
when a window goes fullscreen, and restore the focus to the remembered
window, assuming it's still there, when the fullscreen window is reverted.
>From 52d03243198c2577a464408da0685440752f0cbc Mon Sep 17 00:00:00 2001
From: Iain Patterson <[email protected]>
Date: Thu, 17 Oct 2013 11:08:19 +0100
Subject: [PATCH] Focus fullscreen windows.
Windows which enter fullscreen mode were not automatically given focus.
Usually that didn't matter because they already had focus when they
switched modes. An example of unexpected behaviour is opening a media
file in an already-running vlc from the commandline or via a file manager.
vlc would fullscreen mode but the launching application would retain focus.
Note that if vlc were not already running and it was launched as
described above, it would receive focus when it was opened and thus
retain focus going into fullscreen.
We now track which window had focus before a window enters fullscreen
mode and focus the original window afterwards. In the (usual) case
where the window going fullscreen already had focus, nothing changes.
In the rarer case where the window going fullscreen didn't
have focus, it will gain focus temporarily then yield to the originally
focussed window when it leaves fullscreen mode.
---
src/actions.c | 8 ++++++++
src/screen.h | 3 +++
src/window.c | 5 +++++
3 files changed, 16 insertions(+)
diff --git a/src/actions.c b/src/actions.c
index 65eaa84..17dc965 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -712,6 +712,9 @@ void wFullscreenWindow(WWindow *wwin)
rect = wGetRectForHead(wwin->screen_ptr, head);
wWindowConfigure(wwin, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
+ wwin->screen_ptr->bfs_focused_window = wwin->screen_ptr->focused_window;
+ wSetFocusTo(wwin->screen_ptr, wwin);
+
WMPostNotificationName(WMNChangedState, wwin, "fullscreen");
}
@@ -742,6 +745,11 @@ void wUnfullscreenWindow(WWindow *wwin)
*/
WMPostNotificationName(WMNChangedState, wwin, "fullscreen");
+
+ if (wwin->screen_ptr->bfs_focused_window) {
+ wSetFocusTo(wwin->screen_ptr, wwin->screen_ptr->bfs_focused_window);
+ wwin->screen_ptr->bfs_focused_window = NULL;
+ }
}
#ifdef ANIMATIONS
diff --git a/src/screen.h b/src/screen.h
index bbf57c0..97e2e48 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -97,6 +97,9 @@ typedef struct _WScreen {
* Use this list if you want to
* traverse the entire window list
*/
+ struct WWindow *bfs_focused_window; /* window that had focus before
+ * another window entered fullscreen
+ */
WMArray *selected_windows;
diff --git a/src/window.c b/src/window.c
index d590fab..dc634c8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1455,6 +1455,11 @@ void wUnmanageWindow(WWindow *wwin, Bool restore, Bool destroyed)
if (wwin->flags.menu_open_for_me)
CloseWindowMenu(scr);
+ /* Don't restore focus to this window after a window exits
+ * fullscreen mode */
+ if (scr->bfs_focused_window == wwin)
+ scr->bfs_focused_window = NULL;
+
if (!destroyed) {
if (!wwin->flags.internal_window)
XRemoveFromSaveSet(dpy, wwin->client_win);
--
1.8.3.1