Ladybird/AppKit: Implement a simple TaskManager window

Unlike the Inspector window, this is owned by the ApplicationDelegate as
there should be only a single task manager for the entire application.
This commit is contained in:
Timothy Flynn 2024-04-09 22:35:20 -04:00 committed by Andreas Kling
parent 40a914ce1a
commit 3ab5ecb671
Notes: sideshowbarker 2024-07-16 21:42:29 +09:00
7 changed files with 226 additions and 1 deletions

View File

@ -11,13 +11,14 @@
#import <UI/LadybirdWebView.h>
#import <UI/Tab.h>
#import <UI/TabController.h>
#import <UI/TaskManagerController.h>
#import <Utilities/Conversions.h>
#if !__has_feature(objc_arc)
# error "This project requires ARC"
#endif
@interface ApplicationDelegate ()
@interface ApplicationDelegate () <TaskManagerDelegate>
{
Vector<URL::URL> m_initial_urls;
URL::URL m_new_tab_page_url;
@ -35,6 +36,8 @@
@property (nonatomic, strong) NSMutableArray<TabController*>* managed_tabs;
@property (nonatomic, strong) TaskManagerController* task_manager_controller;
- (NSMenuItem*)createApplicationMenu;
- (NSMenuItem*)createFileMenu;
- (NSMenuItem*)createEditMenu;
@ -119,6 +122,12 @@
- (void)removeTab:(TabController*)controller
{
[self.managed_tabs removeObject:controller];
if ([self.managed_tabs count] == 0u) {
if (self.task_manager_controller != nil) {
[self.task_manager_controller.window close];
}
}
}
- (WebView::CookieJar&)cookieJar
@ -185,6 +194,17 @@
[current_window close];
}
- (void)openTaskManager:(id)sender
{
if (self.task_manager_controller != nil) {
[self.task_manager_controller.window makeKeyAndOrderFront:sender];
return;
}
self.task_manager_controller = [[TaskManagerController alloc] init:self];
[self.task_manager_controller showWindow:nil];
}
- (void)openLocation:(id)sender
{
auto* current_tab = [NSApp keyWindow];
@ -430,6 +450,9 @@
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"Open Inspector"
action:@selector(openInspector:)
keyEquivalent:@"I"]];
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"Open Task Manager"
action:@selector(openTaskManager:)
keyEquivalent:@"M"]];
[menu setSubmenu:submenu];
return menu;
@ -586,4 +609,11 @@
return YES;
}
#pragma mark - TaskManagerDelegate
- (void)onTaskManagerClosed
{
self.task_manager_controller = nil;
}
@end

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#import <System/Cocoa.h>
@class LadybirdWebView;
@interface TaskManager : NSWindow
- (instancetype)init;
@property (nonatomic, strong) LadybirdWebView* web_view;
@end

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/String.h>
#include <LibCore/Timer.h>
#include <LibWebView/ProcessManager.h>
#import <UI/LadybirdWebView.h>
#import <UI/TaskManager.h>
#if !__has_feature(objc_arc)
# error "This project requires ARC"
#endif
static constexpr CGFloat const WINDOW_WIDTH = 400;
static constexpr CGFloat const WINDOW_HEIGHT = 300;
@interface TaskManager ()
{
RefPtr<Core::Timer> m_update_timer;
}
@end
@implementation TaskManager
- (instancetype)init
{
auto tab_rect = [[NSApp keyWindow] frame];
auto position_x = tab_rect.origin.x + (tab_rect.size.width - WINDOW_WIDTH) / 2;
auto position_y = tab_rect.origin.y + (tab_rect.size.height - WINDOW_HEIGHT) / 2;
auto window_rect = NSMakeRect(position_x, position_y, WINDOW_WIDTH, WINDOW_HEIGHT);
auto style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;
self = [super initWithContentRect:window_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO];
if (self) {
self.web_view = [[LadybirdWebView alloc] init:nil];
[self.web_view setPostsBoundsChangedNotifications:YES];
auto* scroll_view = [[NSScrollView alloc] init];
[scroll_view setHasVerticalScroller:YES];
[scroll_view setHasHorizontalScroller:YES];
[scroll_view setLineScroll:24];
[scroll_view setContentView:self.web_view];
[scroll_view setDocumentView:[[NSView alloc] init]];
__weak TaskManager* weak_self = self;
m_update_timer = MUST(Core::Timer::create_repeating(1000, [weak_self] {
TaskManager* strong_self = weak_self;
if (strong_self == nil) {
return;
}
[strong_self updateStatistics];
}));
[self setContentView:scroll_view];
[self setTitle:@"Task Manager"];
[self setIsVisible:YES];
[self updateStatistics];
m_update_timer->start();
}
return self;
}
- (void)updateStatistics
{
WebView::ProcessManager::the().update_all_processes();
[self.web_view loadHTML:WebView::ProcessManager::the().generate_html()];
}
@end

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#import <System/Cocoa.h>
@protocol TaskManagerDelegate <NSObject>
- (void)onTaskManagerClosed;
@end
@interface TaskManagerController : NSWindowController
- (instancetype)init:(id<TaskManagerDelegate>)delegate;
@end

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#import <UI/LadybirdWebView.h>
#import <UI/TaskManager.h>
#import <UI/TaskManagerController.h>
#if !__has_feature(objc_arc)
# error "This project requires ARC"
#endif
@interface TaskManagerController () <NSWindowDelegate>
@property (nonatomic, weak) id<TaskManagerDelegate> delegate;
@end
@implementation TaskManagerController
- (instancetype)init:(id<TaskManagerDelegate>)delegate
{
if (self = [super init]) {
self.delegate = delegate;
}
return self;
}
#pragma mark - Private methods
- (TaskManager*)taskManager
{
return (TaskManager*)[self window];
}
#pragma mark - NSWindowController
- (IBAction)showWindow:(id)sender
{
self.window = [[TaskManager alloc] init];
[self.window setDelegate:self];
[self.window makeKeyAndOrderFront:sender];
}
#pragma mark - NSWindowDelegate
- (void)windowWillClose:(NSNotification*)notification
{
[self.delegate onTaskManagerClosed];
}
- (void)windowDidResize:(NSNotification*)notification
{
if (![[self window] inLiveResize]) {
[[[self taskManager] web_view] handleResize];
}
}
- (void)windowDidChangeBackingProperties:(NSNotification*)notification
{
[[[self taskManager] web_view] handleDevicePixelRatioChange];
}
@end

View File

@ -148,6 +148,8 @@ elseif (APPLE)
AppKit/UI/Palette.mm
AppKit/UI/Tab.mm
AppKit/UI/TabController.mm
AppKit/UI/TaskManager.mm
AppKit/UI/TaskManagerController.mm
AppKit/Utilities/Conversions.mm
)
target_include_directories(ladybird PRIVATE AppKit)

View File

@ -123,6 +123,8 @@ executable("ladybird_executable") {
"AppKit/UI/Palette.mm",
"AppKit/UI/Tab.mm",
"AppKit/UI/TabController.mm",
"AppKit/UI/TaskManager.mm",
"AppKit/UI/TaskManagerController.mm",
"AppKit/Utilities/Conversions.mm",
"AppKit/main.mm",
]