diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index f01cefd55d..d8b0991620 100644 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -456,6 +456,7 @@ int run_in_windowed_mode(RefPtr config, String initial_locatio directory_view.delete_action().activate(); refresh_tree_view(); }); + focus_dependent_delete_action->set_enabled(false); auto mkdir_action = GUI::Action::create("New directory...", { Mod_Ctrl | Mod_Shift, Key_N }, Gfx::Bitmap::load_from_file("/res/icons/16x16/mkdir.png"), [&](const GUI::Action&) { directory_view.mkdir_action().activate(); @@ -579,9 +580,10 @@ int run_in_windowed_mode(RefPtr config, String initial_locatio }; directory_view.on_selection_change = [&](GUI::AbstractView& view) { - // FIXME: Figure out how we can enable/disable the paste action, based on clipboard contents. auto& selection = view.selection(); copy_action->set_enabled(!selection.is_empty()); + focus_dependent_delete_action->set_enabled((!tree_view.selection().is_empty() && tree_view.is_focused()) + || !directory_view.current_view().selection().is_empty()); }; directory_context_menu->add_action(copy_action); @@ -681,6 +683,9 @@ int run_in_windowed_mode(RefPtr config, String initial_locatio }; tree_view.on_selection_change = [&] { + focus_dependent_delete_action->set_enabled((!tree_view.selection().is_empty() && tree_view.is_focused()) + || !directory_view.current_view().selection().is_empty()); + if (tree_view.selection().is_empty()) return; auto path = directories_model->full_path(tree_view.selection().first()); @@ -692,6 +697,11 @@ int run_in_windowed_mode(RefPtr config, String initial_locatio directory_view.delete_action().set_enabled(!tree_view.selection().is_empty()); }; + tree_view.on_focus_change = [&]([[ maybe_unused ]] const bool has_focus, [[ maybe_unused ]] const GUI::FocusSource source) { + focus_dependent_delete_action->set_enabled((!tree_view.selection().is_empty() && has_focus) + || !directory_view.current_view().selection().is_empty()); + }; + tree_view.on_context_menu_request = [&](const GUI::ModelIndex& index, const GUI::ContextMenuEvent& event) { if (index.is_valid()) { tree_view_directory_context_menu->popup(event.screen_position()); diff --git a/Libraries/LibGUI/Widget.h b/Libraries/LibGUI/Widget.h index 10d3366cfc..ec8e5b5f7c 100644 --- a/Libraries/LibGUI/Widget.h +++ b/Libraries/LibGUI/Widget.h @@ -165,6 +165,8 @@ public: bool is_focused() const; void set_focus(bool, FocusSource = FocusSource::Programmatic); + Function on_focus_change; + // Returns true if this widget or one of its descendants is focused. bool has_focus_within() const; diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index 6faaa5a08a..7389b1d350 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -558,14 +558,21 @@ void Window::set_focused_widget(Widget* widget, FocusSource source) { if (m_focused_widget == widget) return; - if (m_focused_widget) { - Core::EventLoop::current().post_event(*m_focused_widget, make(Event::FocusOut, source)); - m_focused_widget->update(); - } + + WeakPtr previously_focused_widget = m_focused_widget; m_focused_widget = widget; + + if (previously_focused_widget) { + Core::EventLoop::current().post_event(*previously_focused_widget, make(Event::FocusOut, source)); + previously_focused_widget->update(); + if (previously_focused_widget && previously_focused_widget->on_focus_change) + previously_focused_widget->on_focus_change(previously_focused_widget->is_focused(), source); + } if (m_focused_widget) { Core::EventLoop::current().post_event(*m_focused_widget, make(Event::FocusIn, source)); m_focused_widget->update(); + if (m_focused_widget && m_focused_widget->on_focus_change) + m_focused_widget->on_focus_change(m_focused_widget->is_focused(), source); } }