From df7fb014e59630653d06387a28b80688384b68d3 Mon Sep 17 00:00:00 2001 From: Iain Patterson 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. 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. --- 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 65eaa844..17dc9651 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 bbf57c04..97e2e48a 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 d590fab1..dc634c80 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);