mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-20 15:09:42 +00:00
LibWebView+UI/AppKit: Display icons in the macOS UI on Tahoe
On macOS Tahoe, it is now recommended to show menu item icons. We use system symbols for this now. Symbols do not have constant variable names and must be found via the SF Symbols app. The symbols chosen here were to match Safari as close as possible.
This commit is contained in:
parent
8ebc20a4f0
commit
ede6314cb6
Notes:
github-actions[bot]
2025-09-17 10:30:06 +00:00
Author: https://github.com/trflynn89
Commit: ede6314cb6
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6215
6 changed files with 95 additions and 14 deletions
|
@ -50,7 +50,8 @@ enum class ActionID {
|
||||||
PauseMedia,
|
PauseMedia,
|
||||||
MuteMedia,
|
MuteMedia,
|
||||||
UnmuteMedia,
|
UnmuteMedia,
|
||||||
ToggleMediaControlsState,
|
ShowControls,
|
||||||
|
HideControls,
|
||||||
ToggleMediaLoopState,
|
ToggleMediaLoopState,
|
||||||
|
|
||||||
ZoomIn,
|
ZoomIn,
|
||||||
|
|
|
@ -908,7 +908,10 @@ void ViewImplementation::initialize_context_menus()
|
||||||
m_media_unmute_action = Action::create("Unmute"sv, ActionID::UnmuteMedia, [this]() {
|
m_media_unmute_action = Action::create("Unmute"sv, ActionID::UnmuteMedia, [this]() {
|
||||||
client().async_toggle_media_mute_state(page_id());
|
client().async_toggle_media_mute_state(page_id());
|
||||||
});
|
});
|
||||||
m_media_controls_action = Action::create_checkable("Show Controls"sv, ActionID::ToggleMediaControlsState, [this]() {
|
m_media_show_controls_action = Action::create("Show Controls"sv, ActionID::ShowControls, [this]() {
|
||||||
|
client().async_toggle_media_controls_state(page_id());
|
||||||
|
});
|
||||||
|
m_media_hide_controls_action = Action::create("Hide Controls"sv, ActionID::HideControls, [this]() {
|
||||||
client().async_toggle_media_controls_state(page_id());
|
client().async_toggle_media_controls_state(page_id());
|
||||||
});
|
});
|
||||||
m_media_loop_action = Action::create_checkable("Loop"sv, ActionID::ToggleMediaLoopState, [this]() {
|
m_media_loop_action = Action::create_checkable("Loop"sv, ActionID::ToggleMediaLoopState, [this]() {
|
||||||
|
@ -947,7 +950,8 @@ void ViewImplementation::initialize_context_menus()
|
||||||
m_media_context_menu->add_action(*m_media_pause_action);
|
m_media_context_menu->add_action(*m_media_pause_action);
|
||||||
m_media_context_menu->add_action(*m_media_mute_action);
|
m_media_context_menu->add_action(*m_media_mute_action);
|
||||||
m_media_context_menu->add_action(*m_media_unmute_action);
|
m_media_context_menu->add_action(*m_media_unmute_action);
|
||||||
m_media_context_menu->add_action(*m_media_controls_action);
|
m_media_context_menu->add_action(*m_media_show_controls_action);
|
||||||
|
m_media_context_menu->add_action(*m_media_hide_controls_action);
|
||||||
m_media_context_menu->add_action(*m_media_loop_action);
|
m_media_context_menu->add_action(*m_media_loop_action);
|
||||||
m_media_context_menu->add_separator();
|
m_media_context_menu->add_separator();
|
||||||
m_media_context_menu->add_action(*m_open_audio_action);
|
m_media_context_menu->add_action(*m_open_audio_action);
|
||||||
|
@ -1027,7 +1031,9 @@ void ViewImplementation::did_request_media_context_menu(Badge<WebContentClient>,
|
||||||
m_media_mute_action->set_visible(!menu.is_muted);
|
m_media_mute_action->set_visible(!menu.is_muted);
|
||||||
m_media_unmute_action->set_visible(menu.is_muted);
|
m_media_unmute_action->set_visible(menu.is_muted);
|
||||||
|
|
||||||
m_media_controls_action->set_checked(menu.has_user_agent_controls);
|
m_media_show_controls_action->set_visible(!menu.has_user_agent_controls);
|
||||||
|
m_media_hide_controls_action->set_visible(menu.has_user_agent_controls);
|
||||||
|
|
||||||
m_media_loop_action->set_checked(menu.is_looping);
|
m_media_loop_action->set_checked(menu.is_looping);
|
||||||
|
|
||||||
if (m_media_context_menu->on_activation)
|
if (m_media_context_menu->on_activation)
|
||||||
|
|
|
@ -331,7 +331,8 @@ protected:
|
||||||
RefPtr<Action> m_media_pause_action;
|
RefPtr<Action> m_media_pause_action;
|
||||||
RefPtr<Action> m_media_mute_action;
|
RefPtr<Action> m_media_mute_action;
|
||||||
RefPtr<Action> m_media_unmute_action;
|
RefPtr<Action> m_media_unmute_action;
|
||||||
RefPtr<Action> m_media_controls_action;
|
RefPtr<Action> m_media_show_controls_action;
|
||||||
|
RefPtr<Action> m_media_hide_controls_action;
|
||||||
RefPtr<Action> m_media_loop_action;
|
RefPtr<Action> m_media_loop_action;
|
||||||
|
|
||||||
Queue<Web::InputEvent> m_pending_input_events;
|
Queue<Web::InputEvent> m_pending_input_events;
|
||||||
|
|
|
@ -19,6 +19,8 @@ NSMenu* create_application_menu(WebView::Menu&);
|
||||||
NSMenu* create_context_menu(LadybirdWebView*, WebView::Menu&);
|
NSMenu* create_context_menu(LadybirdWebView*, WebView::Menu&);
|
||||||
|
|
||||||
NSMenuItem* create_application_menu_item(WebView::Action&);
|
NSMenuItem* create_application_menu_item(WebView::Action&);
|
||||||
NSButton* create_application_button(WebView::Action&, NSImageName);
|
NSButton* create_application_button(WebView::Action&);
|
||||||
|
|
||||||
|
void set_control_image(id control, NSString*);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,29 +115,87 @@ static void initialize_native_control(WebView::Action& action, id control)
|
||||||
{
|
{
|
||||||
switch (action.id()) {
|
switch (action.id()) {
|
||||||
case WebView::ActionID::NavigateBack:
|
case WebView::ActionID::NavigateBack:
|
||||||
|
set_control_image(control, @"chevron.left");
|
||||||
[control setKeyEquivalent:@"["];
|
[control setKeyEquivalent:@"["];
|
||||||
break;
|
break;
|
||||||
case WebView::ActionID::NavigateForward:
|
case WebView::ActionID::NavigateForward:
|
||||||
|
set_control_image(control, @"chevron.right");
|
||||||
[control setKeyEquivalent:@"]"];
|
[control setKeyEquivalent:@"]"];
|
||||||
break;
|
break;
|
||||||
case WebView::ActionID::Reload:
|
case WebView::ActionID::Reload:
|
||||||
|
set_control_image(control, @"arrow.clockwise");
|
||||||
[control setKeyEquivalent:@"r"];
|
[control setKeyEquivalent:@"r"];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WebView::ActionID::CopySelection:
|
case WebView::ActionID::CopySelection:
|
||||||
|
set_control_image(control, @"document.on.document");
|
||||||
[control setKeyEquivalent:@"c"];
|
[control setKeyEquivalent:@"c"];
|
||||||
break;
|
break;
|
||||||
case WebView::ActionID::Paste:
|
case WebView::ActionID::Paste:
|
||||||
|
set_control_image(control, @"document.on.clipboard");
|
||||||
[control setKeyEquivalent:@"v"];
|
[control setKeyEquivalent:@"v"];
|
||||||
break;
|
break;
|
||||||
case WebView::ActionID::SelectAll:
|
case WebView::ActionID::SelectAll:
|
||||||
|
set_control_image(control, @"character.textbox");
|
||||||
[control setKeyEquivalent:@"a"];
|
[control setKeyEquivalent:@"a"];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WebView::ActionID::SearchSelectedText:
|
||||||
|
set_control_image(control, @"magnifyingglass");
|
||||||
|
break;
|
||||||
|
|
||||||
case WebView::ActionID::ViewSource:
|
case WebView::ActionID::ViewSource:
|
||||||
|
set_control_image(control, @"text.document");
|
||||||
[control setKeyEquivalent:@"u"];
|
[control setKeyEquivalent:@"u"];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WebView::ActionID::TakeVisibleScreenshot:
|
||||||
|
case WebView::ActionID::TakeFullScreenshot:
|
||||||
|
set_control_image(control, @"photo");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WebView::ActionID::OpenInNewTab:
|
||||||
|
set_control_image(control, @"plus.square.on.square");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::CopyURL:
|
||||||
|
set_control_image(control, @"document.on.document");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WebView::ActionID::OpenImage:
|
||||||
|
set_control_image(control, @"photo");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::CopyImage:
|
||||||
|
set_control_image(control, @"document.on.document");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WebView::ActionID::OpenAudio:
|
||||||
|
set_control_image(control, @"speaker.wave.1");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::OpenVideo:
|
||||||
|
set_control_image(control, @"video");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::PlayMedia:
|
||||||
|
set_control_image(control, @"play");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::PauseMedia:
|
||||||
|
set_control_image(control, @"pause");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::MuteMedia:
|
||||||
|
set_control_image(control, @"speaker.slash");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::UnmuteMedia:
|
||||||
|
set_control_image(control, @"speaker.wave.2");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::ShowControls:
|
||||||
|
set_control_image(control, @"eye");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::HideControls:
|
||||||
|
set_control_image(control, @"eye.slash");
|
||||||
|
break;
|
||||||
|
case WebView::ActionID::ToggleMediaLoopState:
|
||||||
|
set_control_image(control, @"arrow.clockwise");
|
||||||
|
break;
|
||||||
|
|
||||||
case WebView::ActionID::ZoomIn:
|
case WebView::ActionID::ZoomIn:
|
||||||
[control setKeyEquivalent:@"+"];
|
[control setKeyEquivalent:@"+"];
|
||||||
break;
|
break;
|
||||||
|
@ -213,14 +271,27 @@ NSMenuItem* create_application_menu_item(WebView::Action& action)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSButton* create_application_button(WebView::Action& action, NSImageName image)
|
NSButton* create_application_button(WebView::Action& action)
|
||||||
{
|
{
|
||||||
auto* button = [[NSButton alloc] init];
|
auto* button = [[NSButton alloc] init];
|
||||||
if (image)
|
|
||||||
[button setImage:[NSImage imageNamed:image]];
|
|
||||||
|
|
||||||
initialize_native_control(action, button);
|
initialize_native_control(action, button);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_control_image(id control, NSString* image)
|
||||||
|
{
|
||||||
|
// System symbols are distributed with the San Fransisco (SF) Symbols font. To see all SF Symbols and their names,
|
||||||
|
// you will have to install the SF Symbols app: https://developer.apple.com/sf-symbols/
|
||||||
|
auto set_image = [&]() {
|
||||||
|
[control setImage:[NSImage imageWithSystemSymbolName:image accessibilityDescription:@""]];
|
||||||
|
};
|
||||||
|
|
||||||
|
if (@available(macOS 26, *)) {
|
||||||
|
set_image();
|
||||||
|
} else {
|
||||||
|
if ([control isKindOfClass:[NSButton class]])
|
||||||
|
set_image();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,7 @@ static NSString* const TOOLBAR_TAB_OVERVIEW_IDENTIFIER = @"ToolbarTabOverviewIde
|
||||||
- (NSToolbarItem*)navigate_back_toolbar_item
|
- (NSToolbarItem*)navigate_back_toolbar_item
|
||||||
{
|
{
|
||||||
if (!_navigate_back_toolbar_item) {
|
if (!_navigate_back_toolbar_item) {
|
||||||
auto* button = Ladybird::create_application_button([[[self tab] web_view] view].navigate_back_action(), NSImageNameGoBackTemplate);
|
auto* button = Ladybird::create_application_button([[[self tab] web_view] view].navigate_back_action());
|
||||||
|
|
||||||
_navigate_back_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_NAVIGATE_BACK_IDENTIFIER];
|
_navigate_back_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_NAVIGATE_BACK_IDENTIFIER];
|
||||||
[_navigate_back_toolbar_item setView:button];
|
[_navigate_back_toolbar_item setView:button];
|
||||||
|
@ -272,7 +272,7 @@ static NSString* const TOOLBAR_TAB_OVERVIEW_IDENTIFIER = @"ToolbarTabOverviewIde
|
||||||
- (NSToolbarItem*)navigate_forward_toolbar_item
|
- (NSToolbarItem*)navigate_forward_toolbar_item
|
||||||
{
|
{
|
||||||
if (!_navigate_forward_toolbar_item) {
|
if (!_navigate_forward_toolbar_item) {
|
||||||
auto* button = Ladybird::create_application_button([[[self tab] web_view] view].navigate_forward_action(), NSImageNameGoForwardTemplate);
|
auto* button = Ladybird::create_application_button([[[self tab] web_view] view].navigate_forward_action());
|
||||||
|
|
||||||
_navigate_forward_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_NAVIGATE_FORWARD_IDENTIFIER];
|
_navigate_forward_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_NAVIGATE_FORWARD_IDENTIFIER];
|
||||||
[_navigate_forward_toolbar_item setView:button];
|
[_navigate_forward_toolbar_item setView:button];
|
||||||
|
@ -284,7 +284,7 @@ static NSString* const TOOLBAR_TAB_OVERVIEW_IDENTIFIER = @"ToolbarTabOverviewIde
|
||||||
- (NSToolbarItem*)reload_toolbar_item
|
- (NSToolbarItem*)reload_toolbar_item
|
||||||
{
|
{
|
||||||
if (!_reload_toolbar_item) {
|
if (!_reload_toolbar_item) {
|
||||||
auto* button = Ladybird::create_application_button(WebView::Application::the().reload_action(), NSImageNameRefreshTemplate);
|
auto* button = Ladybird::create_application_button(WebView::Application::the().reload_action());
|
||||||
|
|
||||||
_reload_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_RELOAD_IDENTIFIER];
|
_reload_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_RELOAD_IDENTIFIER];
|
||||||
[_reload_toolbar_item setView:button];
|
[_reload_toolbar_item setView:button];
|
||||||
|
@ -315,7 +315,7 @@ static NSString* const TOOLBAR_TAB_OVERVIEW_IDENTIFIER = @"ToolbarTabOverviewIde
|
||||||
- (NSToolbarItem*)zoom_toolbar_item
|
- (NSToolbarItem*)zoom_toolbar_item
|
||||||
{
|
{
|
||||||
if (!_zoom_toolbar_item) {
|
if (!_zoom_toolbar_item) {
|
||||||
auto* button = Ladybird::create_application_button([[[self tab] web_view] view].reset_zoom_action(), nil);
|
auto* button = Ladybird::create_application_button([[[self tab] web_view] view].reset_zoom_action());
|
||||||
|
|
||||||
_zoom_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_ZOOM_IDENTIFIER];
|
_zoom_toolbar_item = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_ZOOM_IDENTIFIER];
|
||||||
[_zoom_toolbar_item setView:button];
|
[_zoom_toolbar_item setView:button];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue