UI: Add WebContent PID debug preference
Register debug.process.show_web_content_process_id and use it to append the active WebContent process ID to tab titles and tab tooltips in the Qt, Gtk, and AppKit frontends. Keep the stored page title unchanged so toggling the preference can refresh each tab without waiting for a new title update.
This commit is contained in:
parent
5b324718ec
commit
82b270a154
8 changed files with 128 additions and 16 deletions
|
|
@ -60,7 +60,15 @@ static constexpr auto DNS_SETTINGS_KEY = "dnsSettings"sv;
|
|||
|
||||
static constexpr auto CONFIG_VARIABLES_KEY = "configVariables"sv;
|
||||
|
||||
static Array<ConfigVariableDefinition, static_cast<size_t>(ConfigVariableID::Count)> const CONFIG_VARIABLE_DEFINITIONS {};
|
||||
static Array<ConfigVariableDefinition, static_cast<size_t>(ConfigVariableID::Count)> const CONFIG_VARIABLE_DEFINITIONS { {
|
||||
{
|
||||
.id = ConfigVariableID::ShowWebContentProcessIDInTabTitle,
|
||||
.name = "debug.process.show_web_content_process_id"sv,
|
||||
.title = "Show WebContent process ID in tab titles"sv,
|
||||
.description = "Append the active WebContent process ID to each tab title and tooltip."sv,
|
||||
.default_value = false,
|
||||
},
|
||||
} };
|
||||
|
||||
ReadonlySpan<ConfigVariableDefinition const> config_variable_definitions()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ enum class GlobalPrivacyControl {
|
|||
};
|
||||
|
||||
enum class ConfigVariableID : u8 {
|
||||
ShowWebContentProcessIDInTabTitle,
|
||||
Count,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -277,6 +277,9 @@ public:
|
|||
Action& toggle_bookmark_action() { return *m_toggle_bookmark_action; }
|
||||
Action& reset_zoom_action() { return *m_reset_zoom_action; }
|
||||
|
||||
WebContentClient& client();
|
||||
WebContentClient const& client() const;
|
||||
|
||||
virtual Web::DevicePixelSize viewport_size() const = 0;
|
||||
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0;
|
||||
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint content_position) const = 0;
|
||||
|
|
@ -288,8 +291,6 @@ protected:
|
|||
|
||||
ViewImplementation();
|
||||
|
||||
WebContentClient& client();
|
||||
WebContentClient const& client() const;
|
||||
u64 page_id() const;
|
||||
|
||||
void set_url(URL::URL);
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/Resource.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/Settings.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
#include <LibWebView/WebContentClient.h>
|
||||
|
||||
#import <Application/ApplicationDelegate.h>
|
||||
#import <Interface/BookmarksBar.h>
|
||||
|
|
@ -28,6 +31,22 @@ static constexpr CGFloat const WINDOW_HEIGHT = 800;
|
|||
static constexpr CGFloat const TAB_ICON_SIZE = 16;
|
||||
static constexpr NSUInteger const TAB_LOADING_SPINNER_SEGMENT_COUNT = 12;
|
||||
|
||||
class TabSettingsObserver final : public WebView::SettingsObserver {
|
||||
public:
|
||||
explicit TabSettingsObserver(Function<void(WebView::ConfigVariableID)> callback)
|
||||
: m_callback(move(callback))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void config_variable_changed(WebView::ConfigVariableID variable) override
|
||||
{
|
||||
m_callback(variable);
|
||||
}
|
||||
|
||||
private:
|
||||
Function<void(WebView::ConfigVariableID)> m_callback;
|
||||
};
|
||||
|
||||
static NSImage* tab_loading_spinner_icon(NSUInteger frame)
|
||||
{
|
||||
auto* image = [NSImage imageWithSize:NSMakeSize(TAB_ICON_SIZE, TAB_ICON_SIZE)
|
||||
|
|
@ -66,6 +85,7 @@ static NSImage* tab_loading_spinner_icon(NSUInteger frame)
|
|||
BOOL m_loading;
|
||||
NSUInteger m_loading_spinner_frame;
|
||||
__strong NSTimer* m_loading_spinner_timer;
|
||||
OwnPtr<TabSettingsObserver> m_settings_observer;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) NSString* title;
|
||||
|
|
@ -121,6 +141,15 @@ static NSImage* tab_loading_spinner_icon(NSUInteger frame)
|
|||
|
||||
self.favicon = [Tab defaultFavicon];
|
||||
self.title = @"New Tab";
|
||||
__weak Tab* weak_self = self;
|
||||
m_settings_observer = make<TabSettingsObserver>([weak_self](WebView::ConfigVariableID variable) {
|
||||
if (variable != WebView::ConfigVariableID::ShowWebContentProcessIDInTabTitle)
|
||||
return;
|
||||
Tab* strong_self = weak_self;
|
||||
if (strong_self == nil)
|
||||
return;
|
||||
[strong_self updateTabTitleAndFavicon];
|
||||
});
|
||||
[self updateTabTitleAndFavicon];
|
||||
|
||||
[self setTitleVisibility:NSWindowTitleHidden];
|
||||
|
|
@ -193,6 +222,15 @@ static NSImage* tab_loading_spinner_icon(NSUInteger frame)
|
|||
return self.favicon;
|
||||
}
|
||||
|
||||
- (NSString*)displayTitle
|
||||
{
|
||||
if (!WebView::Application::settings().config_variable_as_bool(WebView::ConfigVariableID::ShowWebContentProcessIDInTabTitle))
|
||||
return self.title;
|
||||
|
||||
auto title = MUST(String::formatted("{} [{}]", Ladybird::ns_string_to_string(self.title), [[self web_view] view].client().pid()));
|
||||
return Ladybird::string_to_ns_string(title);
|
||||
}
|
||||
|
||||
- (void)updateLoadingSpinner
|
||||
{
|
||||
if (!m_loading)
|
||||
|
|
@ -255,7 +293,8 @@ static NSImage* tab_loading_spinner_icon(NSUInteger frame)
|
|||
NSFontAttributeName : title_font
|
||||
};
|
||||
|
||||
auto* title_attribute = [[NSAttributedString alloc] initWithString:self.title
|
||||
auto* display_title = [self displayTitle];
|
||||
auto* title_attribute = [[NSAttributedString alloc] initWithString:display_title
|
||||
attributes:title_attributes];
|
||||
|
||||
auto* spacing_attribute = [[NSAttributedString alloc] initWithString:@" "
|
||||
|
|
@ -267,6 +306,8 @@ static NSImage* tab_loading_spinner_icon(NSUInteger frame)
|
|||
[title_and_favicon appendAttributedString:title_attribute];
|
||||
|
||||
[[self tab] setAttributedTitle:title_and_favicon];
|
||||
if ([[self tab] respondsToSelector:@selector(setToolTip:)])
|
||||
[(id)[self tab] setToolTip:display_title];
|
||||
}
|
||||
|
||||
- (void)togglePageMuteState:(id)button
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@
|
|||
#include <LibGfx/Cursor.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/HTML/SelectItem.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/Menu.h>
|
||||
#include <LibWebView/URL.h>
|
||||
#include <LibWebView/WebContentClient.h>
|
||||
#include <UI/Gtk/BrowserWindow.h>
|
||||
#include <UI/Gtk/Dialogs.h>
|
||||
#include <UI/Gtk/Events.h>
|
||||
|
|
@ -89,16 +91,20 @@ Tab::Tab(BrowserWindow& window, RefPtr<WebView::WebContentClient> parent_client,
|
|||
|
||||
Tab::~Tab() = default;
|
||||
|
||||
void Tab::set_tab_page(AdwTabPage* page)
|
||||
{
|
||||
m_tab_page = page;
|
||||
update_tab_title();
|
||||
}
|
||||
|
||||
void Tab::setup_callbacks()
|
||||
{
|
||||
auto* root = GTK_WIDGET(m_web_view);
|
||||
|
||||
m_view->on_title_change = [this](auto const& title) {
|
||||
if (m_tab_page) {
|
||||
auto utf8 = title.to_utf8();
|
||||
auto byte_str = ByteString(utf8.bytes_as_string_view());
|
||||
adw_tab_page_set_title(m_tab_page, byte_str.characters());
|
||||
}
|
||||
auto utf8 = title.to_utf8();
|
||||
m_title = ByteString(utf8.bytes_as_string_view());
|
||||
update_tab_title();
|
||||
};
|
||||
|
||||
m_view->on_url_change = [this](auto const& url) {
|
||||
|
|
@ -273,6 +279,30 @@ void Tab::setup_callbacks()
|
|||
create_context_menu(*root, *m_view, m_view->media_context_menu());
|
||||
}
|
||||
|
||||
ByteString Tab::tab_title() const
|
||||
{
|
||||
if (!WebView::Application::settings().config_variable_as_bool(WebView::ConfigVariableID::ShowWebContentProcessIDInTabTitle))
|
||||
return m_title;
|
||||
|
||||
return ByteString::formatted("{} [{}]", m_title, m_view->client().pid());
|
||||
}
|
||||
|
||||
void Tab::update_tab_title()
|
||||
{
|
||||
if (!m_tab_page)
|
||||
return;
|
||||
|
||||
auto title = tab_title();
|
||||
adw_tab_page_set_title(m_tab_page, title.characters());
|
||||
adw_tab_page_set_tooltip(m_tab_page, title.characters());
|
||||
}
|
||||
|
||||
void Tab::config_variable_changed(WebView::ConfigVariableID variable)
|
||||
{
|
||||
if (variable == WebView::ConfigVariableID::ShowWebContentProcessIDInTabTitle)
|
||||
update_tab_title();
|
||||
}
|
||||
|
||||
void Tab::navigate(URL::URL const& url)
|
||||
{
|
||||
m_view->load(url);
|
||||
|
|
|
|||
11
UI/Gtk/Tab.h
11
UI/Gtk/Tab.h
|
|
@ -14,6 +14,7 @@
|
|||
#include <LibWeb/HTML/ActivateTab.h>
|
||||
#include <LibWeb/HTML/SelectItem.h>
|
||||
#include <LibWebView/Forward.h>
|
||||
#include <LibWebView/Settings.h>
|
||||
#include <UI/Gtk/GLibPtr.h>
|
||||
#include <UI/Gtk/Widgets/LadybirdWebView.h>
|
||||
|
||||
|
|
@ -24,11 +25,11 @@ namespace Ladybird {
|
|||
class BrowserWindow;
|
||||
class WebContentView;
|
||||
|
||||
class Tab {
|
||||
class Tab : public WebView::SettingsObserver {
|
||||
public:
|
||||
Tab(BrowserWindow& window, URL::URL url = {});
|
||||
Tab(BrowserWindow& window, WebView::WebContentClient& parent_client, u64 page_index);
|
||||
~Tab();
|
||||
virtual ~Tab() override;
|
||||
|
||||
GtkWidget* widget() const { return GTK_WIDGET(m_web_view); }
|
||||
WebContentView& view() { return *m_view; }
|
||||
|
|
@ -39,11 +40,14 @@ public:
|
|||
bool is_loading() const { return m_is_loading; }
|
||||
|
||||
AdwTabPage* tab_page() const { return m_tab_page; }
|
||||
void set_tab_page(AdwTabPage* page) { m_tab_page = page; }
|
||||
void set_tab_page(AdwTabPage*);
|
||||
|
||||
private:
|
||||
Tab(BrowserWindow& window, RefPtr<WebView::WebContentClient> parent_client, size_t page_index);
|
||||
void setup_callbacks();
|
||||
void update_tab_title();
|
||||
ByteString tab_title() const;
|
||||
virtual void config_variable_changed(WebView::ConfigVariableID) override;
|
||||
void show_select_dropdown(Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items);
|
||||
|
||||
BrowserWindow& m_window;
|
||||
|
|
@ -53,6 +57,7 @@ private:
|
|||
AdwTabPage* m_tab_page { nullptr };
|
||||
|
||||
URL::URL m_initial_url;
|
||||
ByteString m_title { "New Tab" };
|
||||
GObjectPtr<GdkPaintable> m_favicon;
|
||||
bool m_is_loading { false };
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <LibWeb/HTML/SelectedFile.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/Utilities.h>
|
||||
#include <LibWebView/WebContentClient.h>
|
||||
#include <UI/Qt/BrowserWindow.h>
|
||||
#include <UI/Qt/Icon.h>
|
||||
#include <UI/Qt/Menu.h>
|
||||
|
|
@ -184,7 +185,7 @@ Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client,
|
|||
auto url_serialized = qstring_from_ak_string(url.serialize());
|
||||
|
||||
m_title = url_serialized;
|
||||
emit title_changed(tab_index(), url_serialized);
|
||||
update_tab_title();
|
||||
|
||||
m_favicon = default_favicon();
|
||||
set_loading(true);
|
||||
|
|
@ -213,7 +214,7 @@ Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client,
|
|||
|
||||
view().on_title_change = [this](auto const& title) {
|
||||
m_title = qstring_from_utf16_string(title);
|
||||
emit title_changed(tab_index(), m_title);
|
||||
update_tab_title();
|
||||
};
|
||||
|
||||
view().on_favicon_change = [this](auto const& bitmap) {
|
||||
|
|
@ -525,6 +526,25 @@ QIcon Tab::tab_icon() const
|
|||
return m_favicon;
|
||||
}
|
||||
|
||||
QString Tab::title() const
|
||||
{
|
||||
if (!WebView::Application::settings().config_variable_as_bool(WebView::ConfigVariableID::ShowWebContentProcessIDInTabTitle))
|
||||
return m_title;
|
||||
|
||||
return QString("%1 [%2]").arg(m_title).arg(view().client().pid());
|
||||
}
|
||||
|
||||
void Tab::update_tab_title()
|
||||
{
|
||||
emit title_changed(tab_index(), title());
|
||||
}
|
||||
|
||||
void Tab::config_variable_changed(WebView::ConfigVariableID variable)
|
||||
{
|
||||
if (variable == WebView::ConfigVariableID::ShowWebContentProcessIDInTabTitle)
|
||||
update_tab_title();
|
||||
}
|
||||
|
||||
void Tab::set_loading(bool is_loading)
|
||||
{
|
||||
if (m_is_loading == is_loading)
|
||||
|
|
|
|||
10
UI/Qt/Tab.h
10
UI/Qt/Tab.h
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/HTML/AudioPlayState.h>
|
||||
#include <LibWebView/Settings.h>
|
||||
#include <UI/Qt/BookmarksBar.h>
|
||||
#include <UI/Qt/FindInPageWidget.h>
|
||||
#include <UI/Qt/LocationEdit.h>
|
||||
|
|
@ -46,7 +47,9 @@ signals:
|
|||
void mouse_entered(QEnterEvent*);
|
||||
};
|
||||
|
||||
class Tab final : public QWidget {
|
||||
class Tab final
|
||||
: public QWidget
|
||||
, public WebView::SettingsObserver {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
|
@ -54,6 +57,7 @@ public:
|
|||
virtual ~Tab() override;
|
||||
|
||||
WebContentView& view() { return *m_view; }
|
||||
WebContentView const& view() const { return *m_view; }
|
||||
|
||||
void navigate(URL::URL const&);
|
||||
void load_html(StringView);
|
||||
|
|
@ -70,7 +74,7 @@ public:
|
|||
|
||||
QIcon const& favicon() const { return m_favicon; }
|
||||
QIcon tab_icon() const;
|
||||
QString const& title() const { return m_title; }
|
||||
QString title() const;
|
||||
|
||||
QMenu* context_menu() const { return m_context_menu; }
|
||||
|
||||
|
|
@ -93,8 +97,10 @@ signals:
|
|||
private:
|
||||
virtual void resizeEvent(QResizeEvent*) override;
|
||||
virtual bool event(QEvent*) override;
|
||||
virtual void config_variable_changed(WebView::ConfigVariableID) override;
|
||||
|
||||
void recreate_toolbar_icons();
|
||||
void update_tab_title();
|
||||
void set_loading(bool);
|
||||
void update_tab_icon();
|
||||
int tab_index();
|
||||
|
|
|
|||
Loading…
Reference in a new issue