Skip to content

Commit

Permalink
Correctly preserve focus state after minimising and restoring
Browse files Browse the repository at this point in the history
The previously focused window was not refocused after minimising and restoring the main window.

This reworks the focus restoration logic to fix that.
  • Loading branch information
reupen committed Jan 29, 2025
1 parent f5e81b2 commit 2657811
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
foobar2000 was minimised to the system tray.
[[#1110](https://github.com/reupen/columns_ui/pull/1110)]

- A bug where the keyboard focus changed after minimising and restoring
foobar2000 was fixed.
[[#1109](https://github.com/reupen/columns_ui/pull/1109)]

- Some logic that normally occurs when main window is activated or focused was
surpressed while foobar2000 is exiting, as that logic is unnecessary at that
point. [[#1109](https://github.com/reupen/columns_ui/pull/1109)]
Expand Down
19 changes: 19 additions & 0 deletions foo_ui_columns/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,25 @@ void cui::MainWindow::update_taskbar_buttons(bool update) const
}
}

void cui::MainWindow::save_focus_state()
{
HWND wnd_focused_before_menu{};

if (!rebar::g_rebar_window || !rebar::g_rebar_window->get_previous_menu_focus_window(wnd_focused_before_menu))
wnd_focused_before_menu = g_layout_window.get_previous_menu_focus_window();

if (wnd_focused_before_menu) {
m_last_focused_wnd = wnd_focused_before_menu;
return;
}

HWND wnd_focus = GetFocus();
if (wnd_focus && IsChild(m_wnd, wnd_focus))
m_last_focused_wnd = wnd_focus;
else
m_last_focused_wnd = nullptr;
}

void cui::MainWindow::queue_taskbar_button_update(bool update)
{
PostMessage(m_wnd, update ? MSG_UPDATE_TASKBAR_BUTTONS : MSG_CREATE_TASKBAR_BUTTONS, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion foo_ui_columns/main_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ class MainWindow {
void set_title(const char* ptr);
bool update_taskbar_button_images() const;
void update_taskbar_buttons(bool update) const;
void save_focus_state();

pfc::string8 m_window_title;
wil::com_ptr<ITaskbarList3> m_taskbar_list;
HWND m_wnd{};
HWND m_last_focused_wnd{};
HWND m_wnd_focused_before_menu{};
HMONITOR m_monitor{};
user_interface::HookProc_t m_hook_proc{};
bool m_should_handle_multimedia_keys{true};
Expand Down
60 changes: 36 additions & 24 deletions foo_ui_columns/mw_wnd_proc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,43 +239,55 @@ LRESULT cui::MainWindow::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
case WM_DISPLAYCHANGE:
RedrawWindow(wnd, nullptr, nullptr, RDW_ALLCHILDREN | RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
break;
case WM_ACTIVATE:
if ((LOWORD(wp) != WA_INACTIVE) || m_is_destroying)
break;
case WM_ACTIVATE: {
const auto is_minimised = HIWORD(wp);
const auto state = LOWORD(wp);

if (!uih::are_keyboard_cues_enabled())
SendMessage(wnd, WM_UPDATEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEFOCUS), NULL);
if (m_is_destroying || state != WA_INACTIVE)
return 0;

m_last_focused_wnd = GetFocus();
if (!is_minimised)
save_focus_state();

if (!rebar::g_rebar_window || !rebar::g_rebar_window->get_previous_menu_focus_window(m_wnd_focused_before_menu))
m_wnd_focused_before_menu = g_layout_window.get_previous_menu_focus_window();
if (!uih::are_keyboard_cues_enabled())
SendMessage(wnd, WM_UPDATEUISTATE, MAKEWPARAM(UIS_SET, UISF_HIDEFOCUS), NULL);

if (rebar::g_rebar_window)
rebar::g_rebar_window->hide_accelerators();

g_layout_window.hide_menu_access_keys();

break;
return 0;
}
case WM_SETFOCUS:
if (!m_is_destroying) {
HWND wnd_focus = m_wnd_focused_before_menu ? m_wnd_focused_before_menu : m_last_focused_wnd;
if (wnd_focus && IsWindow(wnd_focus))
SetFocus(wnd_focus);
else
g_layout_window.set_focus();
}
if (m_is_destroying)
break;

if (m_last_focused_wnd && IsWindow(m_last_focused_wnd))
SetFocus(m_last_focused_wnd);
else
g_layout_window.set_focus();
break;
case WM_SYSCOMMAND:
if (wp == SC_KEYMENU && !lp) {
if (!HIBYTE(GetKeyState(VK_CONTROL))) // Workaround for obscure OS bug involving global keyboard shortcuts
{
if (rebar::g_rebar_window && rebar::g_rebar_window->set_menu_focus())
g_layout_window.hide_menu_access_keys();
else
g_layout_window.set_menu_focus();
}
switch (wp) {
case SC_KEYMENU:
if (lp)
break;

// Workaround for obscure OS bug involving global keyboard shortcuts
if (HIBYTE(GetKeyState(VK_CONTROL)))
break;

if (rebar::g_rebar_window && rebar::g_rebar_window->set_menu_focus())
g_layout_window.hide_menu_access_keys();
else
g_layout_window.set_menu_focus();

return 0;
case SC_MINIMIZE:
if (GetForegroundWindow() == wnd)
save_focus_state();
break;
}
break;
case WM_MENUCHAR: {
Expand Down

0 comments on commit 2657811

Please sign in to comment.