mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-06 09:36:08 +00:00
UI/AppKit: Add UI components to enable DevTools at runtime
This commit is contained in:
parent
df7917d705
commit
28574e2812
Notes:
github-actions[bot]
2025-03-15 18:10:45 +00:00
Author: https://github.com/trflynn89
Commit: 28574e2812
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3956
4 changed files with 188 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2023-2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2023-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -9,6 +9,7 @@
|
|||
#include <LibWebView/SearchEngine.h>
|
||||
|
||||
#import <Application/ApplicationDelegate.h>
|
||||
#import <Interface/InfoBar.h>
|
||||
#import <Interface/LadybirdWebView.h>
|
||||
#import <Interface/Tab.h>
|
||||
#import <Interface/TabController.h>
|
||||
|
@ -42,8 +43,12 @@
|
|||
@property (nonatomic, strong) NSMutableArray<TabController*>* managed_tabs;
|
||||
@property (nonatomic, weak) Tab* active_tab;
|
||||
|
||||
@property (nonatomic, strong) InfoBar* info_bar;
|
||||
|
||||
@property (nonatomic, strong) TaskManagerController* task_manager_controller;
|
||||
|
||||
@property (nonatomic, strong) NSMenuItem* toggle_devtools_menu_item;
|
||||
|
||||
- (NSMenuItem*)createApplicationMenu;
|
||||
- (NSMenuItem*)createFileMenu;
|
||||
- (NSMenuItem*)createEditMenu;
|
||||
|
@ -133,6 +138,10 @@
|
|||
- (void)setActiveTab:(Tab*)tab
|
||||
{
|
||||
self.active_tab = tab;
|
||||
|
||||
if (self.info_bar) {
|
||||
[self.info_bar tabBecameActive:self.active_tab];
|
||||
}
|
||||
}
|
||||
|
||||
- (Tab*)activeTab
|
||||
|
@ -237,6 +246,57 @@
|
|||
[current_window close];
|
||||
}
|
||||
|
||||
- (void)toggleDevToolsEnabled:(id)sender
|
||||
{
|
||||
if (auto result = WebView::Application::the().toggle_devtools_enabled(); result.is_error()) {
|
||||
auto error_message = MUST(String::formatted("Unable to start DevTools: {}", result.error()));
|
||||
|
||||
auto* dialog = [[NSAlert alloc] init];
|
||||
[dialog setMessageText:Ladybird::string_to_ns_string(error_message)];
|
||||
|
||||
[dialog beginSheetModalForWindow:self.active_tab
|
||||
completionHandler:nil];
|
||||
} else {
|
||||
switch (result.value()) {
|
||||
case WebView::Application::DevtoolsState::Disabled:
|
||||
[self devtoolsDisabled];
|
||||
break;
|
||||
case WebView::Application::DevtoolsState::Enabled:
|
||||
[self devtoolsEnabled];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)devtoolsDisabled
|
||||
{
|
||||
[self.toggle_devtools_menu_item setTitle:@"Enable DevTools"];
|
||||
|
||||
if (self.info_bar) {
|
||||
[self.info_bar hide];
|
||||
self.info_bar = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)devtoolsEnabled
|
||||
{
|
||||
[self.toggle_devtools_menu_item setTitle:@"Disable DevTools"];
|
||||
|
||||
if (!self.info_bar) {
|
||||
self.info_bar = [[InfoBar alloc] init];
|
||||
}
|
||||
|
||||
auto message = MUST(String::formatted("DevTools is enabled on port {}", WebView::Application::chrome_options().devtools_port));
|
||||
|
||||
[self.info_bar showWithMessage:Ladybird::string_to_ns_string(message)
|
||||
dismissButtonTooltip:@"Disable DevTools"
|
||||
dismissButtonClicked:^{
|
||||
MUST(WebView::Application::the().toggle_devtools_enabled());
|
||||
[self devtoolsDisabled];
|
||||
}
|
||||
activeTab:self.active_tab];
|
||||
}
|
||||
|
||||
- (void)openTaskManager:(id)sender
|
||||
{
|
||||
if (self.task_manager_controller != nil) {
|
||||
|
@ -608,6 +668,12 @@
|
|||
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"View Source"
|
||||
action:@selector(viewSource:)
|
||||
keyEquivalent:@""]];
|
||||
|
||||
self.toggle_devtools_menu_item = [[NSMenuItem alloc] initWithTitle:@"Enable DevTools"
|
||||
action:@selector(toggleDevToolsEnabled:)
|
||||
keyEquivalent:@"I"];
|
||||
[submenu addItem:self.toggle_devtools_menu_item];
|
||||
|
||||
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"Open Task Manager"
|
||||
action:@selector(openTaskManager:)
|
||||
keyEquivalent:@"M"]];
|
||||
|
|
|
@ -3,6 +3,7 @@ add_library(ladybird_impl STATIC
|
|||
Application/Application.mm
|
||||
Application/ApplicationDelegate.mm
|
||||
Interface/Event.mm
|
||||
Interface/InfoBar.mm
|
||||
Interface/LadybirdWebView.mm
|
||||
Interface/LadybirdWebViewBridge.cpp
|
||||
Interface/LadybirdWebViewWindow.mm
|
||||
|
|
25
UI/AppKit/Interface/InfoBar.h
Normal file
25
UI/AppKit/Interface/InfoBar.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@class Tab;
|
||||
|
||||
using InfoBarDismissed = void (^)(void);
|
||||
|
||||
@interface InfoBar : NSStackView
|
||||
|
||||
- (void)showWithMessage:(NSString*)message
|
||||
dismissButtonTooltip:(NSString*)tooltip
|
||||
dismissButtonClicked:(InfoBarDismissed)on_dimissed
|
||||
activeTab:(Tab*)tab;
|
||||
- (void)hide;
|
||||
|
||||
- (void)tabBecameActive:(Tab*)tab;
|
||||
|
||||
@end
|
95
UI/AppKit/Interface/InfoBar.mm
Normal file
95
UI/AppKit/Interface/InfoBar.mm
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#import <Interface/InfoBar.h>
|
||||
#import <Interface/Tab.h>
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
# error "This project requires ARC"
|
||||
#endif
|
||||
|
||||
static constexpr CGFloat const INFO_BAR_HEIGHT = 40;
|
||||
|
||||
@interface InfoBar ()
|
||||
|
||||
@property (nonatomic, strong) NSTextField* text_label;
|
||||
@property (nonatomic, strong) NSButton* dismiss_button;
|
||||
@property (nonatomic, copy) InfoBarDismissed on_dimissed;
|
||||
|
||||
@end
|
||||
|
||||
@implementation InfoBar
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
self.text_label = [NSTextField labelWithString:@""];
|
||||
|
||||
self.dismiss_button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameStopProgressTemplate]
|
||||
target:self
|
||||
action:@selector(dismiss:)];
|
||||
[self.dismiss_button setBezelStyle:NSBezelStyleAccessoryBarAction];
|
||||
|
||||
[self addView:self.text_label inGravity:NSStackViewGravityLeading];
|
||||
[self addView:self.dismiss_button inGravity:NSStackViewGravityTrailing];
|
||||
|
||||
[self setOrientation:NSUserInterfaceLayoutOrientationHorizontal];
|
||||
[self setEdgeInsets:NSEdgeInsets { 0, 8, 0, 8 }];
|
||||
|
||||
[[self heightAnchor] constraintEqualToConstant:INFO_BAR_HEIGHT].active = YES;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)showWithMessage:(NSString*)message
|
||||
dismissButtonTooltip:(NSString*)tooltip
|
||||
dismissButtonClicked:(InfoBarDismissed)on_dimissed
|
||||
activeTab:(Tab*)tab
|
||||
{
|
||||
[self.text_label setStringValue:message];
|
||||
|
||||
[self.dismiss_button setToolTip:tooltip];
|
||||
self.on_dimissed = on_dimissed;
|
||||
|
||||
if (tab) {
|
||||
[self attachToTab:tab];
|
||||
}
|
||||
|
||||
[self setHidden:NO];
|
||||
}
|
||||
|
||||
- (void)dismiss:(id)sender
|
||||
{
|
||||
if (self.on_dimissed) {
|
||||
self.on_dimissed();
|
||||
}
|
||||
|
||||
[self hide];
|
||||
}
|
||||
|
||||
- (void)hide
|
||||
{
|
||||
[self removeFromSuperview];
|
||||
[self setHidden:YES];
|
||||
}
|
||||
|
||||
- (void)tabBecameActive:(Tab*)tab
|
||||
{
|
||||
if (![self isHidden]) {
|
||||
[self attachToTab:tab];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)attachToTab:(Tab*)tab
|
||||
{
|
||||
[self removeFromSuperview];
|
||||
|
||||
[tab.contentView addView:self inGravity:NSStackViewGravityTrailing];
|
||||
[[self leadingAnchor] constraintEqualToAnchor:[tab.contentView leadingAnchor]].active = YES;
|
||||
}
|
||||
|
||||
@end
|
Loading…
Add table
Add a link
Reference in a new issue