ladybird/UI/Qt/Application.h
Andreas Kling b91ff9ebfd UI/Qt: Keep macOS app alive without windows
Disable Qt quit-on-last-window behavior on macOS and install an
application-level menu so useful commands remain available after the
last browser window closes.

Reuse shared application actions and menus for Settings, Bookmarks,
History, Help, and global appearance controls. Centralize window-aware
commands such as New Tab, New Window, Open File, Open Location, and
Reopen Recently Closed so the browser window and windowless app menu
use the same behavior. Keep the location editor focused for new blank
windows after the native window has been activated.
2026-06-22 01:13:53 +02:00

95 lines
4.2 KiB
C++

/*
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Function.h>
#include <LibURL/URL.h>
#include <LibWebView/Application.h>
#include <UI/Qt/BrowserWindow.h>
#include <QApplication>
class QMenu;
namespace Ladybird {
struct WindowConfiguration {
Optional<Web::DevicePixels> x {};
Optional<Web::DevicePixels> y {};
Optional<Web::DevicePixels> width {};
Optional<Web::DevicePixels> height {};
Optional<bool> maximized {};
};
class Application final : public WebView::Application {
WEB_VIEW_APPLICATION(Application)
public:
virtual ~Application() override;
Function<void(URL::URL)> on_open_file;
BrowserWindow& new_window(Vector<URL::URL> const& initial_urls, WindowConfiguration const& = {}, BrowserWindow::IsPopupWindow is_popup_window = BrowserWindow::IsPopupWindow::No, Tab* parent_tab = nullptr, Optional<u64> page_index = {});
void open_new_tab();
void open_new_window();
void focus_location_editor();
void reopen_recently_closed_tab();
void open_file();
void quit();
void initialize_macos_application_menu();
QMenu* qt_bookmarks_menu() const;
BrowserWindow& active_window() const { return *m_active_window; }
void set_active_window(BrowserWindow& w) { m_active_window = &w; }
BrowserWindow* active_window_if_any() const { return m_active_window; }
Tab* active_tab() const { return m_active_window ? m_active_window->current_tab() : nullptr; }
void update_reopen_recently_closed_actions() const;
private:
explicit Application();
virtual void create_platform_options(WebView::BrowserOptions&, WebView::RequestServerOptions&, WebView::WebContentOptions&) override;
virtual Core::EventLoop& create_platform_event_loop() override;
virtual Optional<WebView::ViewImplementation&> active_web_view() const override;
virtual Optional<WebView::ViewImplementation&> open_blank_new_tab(Web::HTML::ActivateTab) const override;
virtual void open_url_in_new_tab(URL::URL const&, Web::HTML::ActivateTab) const override;
virtual bool activate_tab_with_url(URL::URL const&) const override;
virtual void open_url_in_new_window(URL::URL const& url) override;
virtual Optional<ByteString> ask_user_for_download_path(StringView file) const override;
virtual void display_download_confirmation_dialog(StringView download_name, LexicalPath const& path) const override;
virtual void display_error_dialog(StringView error_message) const override;
virtual bool supports_clipboard_type(ClipboardType) const override;
virtual Utf16String clipboard_text(ClipboardType) const override;
virtual void set_clipboard_text(String, ClipboardType = ClipboardType::Text) override;
virtual Vector<Web::Clipboard::SystemClipboardRepresentation> clipboard_entries() const override;
virtual void insert_clipboard_entry(Web::Clipboard::SystemClipboardRepresentation) override;
virtual bool supports_vertical_tabs() const override { return true; }
virtual bool supports_server_side_window_decorations() const override { return true; }
virtual void update_tabs_display() const override;
virtual void rebuild_bookmarks_menu() const override;
virtual void show_bookmark_context_menu(Gfx::IntPoint, Optional<WebView::BookmarkItem const&>, Optional<String const&> target_folder_id) override;
virtual Optional<BookmarkID> bookmark_item_id_for_context_menu() const override;
virtual NonnullRefPtr<BookmarkPromise> display_add_bookmark_dialog() const override;
virtual NonnullRefPtr<BookmarkPromise> display_edit_bookmark_dialog(WebView::BookmarkItem::Bookmark const& current_bookmark) const override;
virtual NonnullRefPtr<BookmarkFolderPromise> display_add_bookmark_folder_dialog() const override;
virtual NonnullRefPtr<BookmarkFolderPromise> display_edit_bookmark_folder_dialog(WebView::BookmarkItem::Folder const& current_folder) const override;
virtual void on_devtools_enabled() const override;
virtual void on_devtools_disabled() const override;
virtual void on_recently_closed_entries_changed() const override;
OwnPtr<QApplication> m_application;
BrowserWindow* m_active_window { nullptr };
};
}