From 9e64d4c7cfde4dc93fe1d6bf6b4590ad5693bb08 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sat, 6 Jun 2026 18:46:48 +0200 Subject: [PATCH] toolkit update: fix note title updates --- ui/cocoa/EventData.h | 2 +- ui/cocoa/MainWindow.h | 5 ++-- ui/cocoa/MainWindow.m | 52 ++++++++++++++++++++++++++++++++++++---- ui/cocoa/Toolbar.h | 2 +- ui/cocoa/WindowManager.h | 10 +++++--- ui/cocoa/WindowManager.m | 18 ++++++++++---- ui/cocoa/appdelegate.m | 9 +++++-- ui/cocoa/button.m | 6 ++--- ui/cocoa/text.m | 6 +++-- ui/cocoa/toolkit.h | 3 --- ui/cocoa/toolkit.m | 32 +------------------------ ui/cocoa/webview.m | 2 +- ui/cocoa/window.m | 24 +++++++++++++++---- ui/common/types.c | 5 +++- 14 files changed, 112 insertions(+), 64 deletions(-) diff --git a/ui/cocoa/EventData.h b/ui/cocoa/EventData.h index f82f1d4..f0c8eac 100644 --- a/ui/cocoa/EventData.h +++ b/ui/cocoa/EventData.h @@ -29,7 +29,7 @@ #import "../ui/toolkit.h" #import "../common/context.h" -typedef void(*get_eventdata_func)(id sender, UiVar *var, void **eventdata, int *eventdatatype, int *value); +typedef void(*get_eventdata_func)(id sender, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value); @interface EventData : NSObject @property UiObject *obj; diff --git a/ui/cocoa/MainWindow.h b/ui/cocoa/MainWindow.h index 7c8cbf6..52ad47f 100644 --- a/ui/cocoa/MainWindow.h +++ b/ui/cocoa/MainWindow.h @@ -29,7 +29,7 @@ #import "toolkit.h" #import "../ui/window.h" -@interface MainWindow : NSWindow +@interface MainWindow : NSWindow @property UiObject *obj; @property (strong) NSSplitView *splitview; @@ -38,7 +38,8 @@ @property (strong) NSView *rightPanel; @property int topOffset; -- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview; +- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview width:(int)width height:(int)height; +- (void) saveWindowSize; @end diff --git a/ui/cocoa/MainWindow.m b/ui/cocoa/MainWindow.m index d46025f..944c9aa 100644 --- a/ui/cocoa/MainWindow.m +++ b/ui/cocoa/MainWindow.m @@ -27,6 +27,7 @@ */ #import "MainWindow.h" +#import "WindowManager.h" #import "container.h" #import "GridLayout.h" #import "BoxContainer.h" @@ -38,10 +39,12 @@ #import "menu.h" #import "Toolbar.h" + + @implementation MainWindow -- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview{ - NSRect frame = NSMakeRect(300, 200, 600, 500); +- (MainWindow*)init:(UiObject*)obj withSidebar:(BOOL)hasSidebar withSplitview:(BOOL)hasSplitview width:(int)width height:(int)height { + NSRect frame = NSMakeRect(300, 200, width, height); self = [self initWithContentRect:frame styleMask:NSWindowStyleMaskTitled | @@ -51,7 +54,7 @@ backing:NSBackingStoreBuffered defer:false]; _obj = obj; - + self.delegate = self; int top = 4; NSView *content = self.contentView; @@ -137,10 +140,21 @@ [self setToolbar:toolbar]; } - return self; } +- (void) saveWindowSize { + CGSize size = self.frame.size; + if(size.width > 0 && size.height > 0) { + char width_str[32]; + char height_str[32]; + snprintf(width_str, 32, "%d", (int)size.width); + snprintf(height_str, 32, "%d", (int)size.height); + ui_set_property("ui.window.width", width_str); + ui_set_property("ui.window.height", height_str); + } +} + - (BOOL) getIsVisible { return [self isVisible]; } @@ -153,7 +167,37 @@ } } +- (void) windowWillClose:(NSNotification *) notification { + UiObject *obj = _obj; + + if(obj->onclose) { + UiEvent event; + memset(&event, 0, sizeof(UiEvent)); + event.obj = obj; + event.window = obj->window; + event.document = obj->ctx->document; + obj->onclose(&event, obj->onclosedata); + } + + if(obj->ref > 0) { + obj->ref--; + } else { + // warn about invalid reference counting + NSLog(@"Error: UiObject %p ref == 0\n", obj); + } + + if(obj->ref == 0) { + [self saveWindowSize]; + // this cleans up any widget references from the context + uic_context_prepare_close(obj->ctx); + [[WindowManager sharedWindowManager] closeWindow:self]; + } +} +- (void) dealloc { + uic_object_destroy(_obj); + NSLog(@"MainWindow dealloc"); +} @end diff --git a/ui/cocoa/Toolbar.h b/ui/cocoa/Toolbar.h index 7ec7bbd..042fa24 100644 --- a/ui/cocoa/Toolbar.h +++ b/ui/cocoa/Toolbar.h @@ -50,7 +50,7 @@ NSMutableArray *defaultItems; } -@property MainWindow *window; +@property (weak) MainWindow *window; @property UiObject *obj; - (UiToolbar*) initWithWindow:(MainWindow*)window; diff --git a/ui/cocoa/WindowManager.h b/ui/cocoa/WindowManager.h index 7f1b225..76e3c65 100644 --- a/ui/cocoa/WindowManager.h +++ b/ui/cocoa/WindowManager.h @@ -28,14 +28,18 @@ #import "toolkit.h" -@interface WindowManager : NSObject +@interface WindowManager : NSObject -@property NSMutableArray *windows; +@property NSMutableArray *windows; + (WindowManager*) sharedWindowManager; - (WindowManager*)init; -- (void)addWindow:(NSWindow*)win; +- (void)addWindow:(NSWindowController*)win; + +- (void)closeWindow:(NSWindow*)win; + +- (void)shutdown; @end diff --git a/ui/cocoa/WindowManager.m b/ui/cocoa/WindowManager.m index ca03182..9b5d04a 100644 --- a/ui/cocoa/WindowManager.m +++ b/ui/cocoa/WindowManager.m @@ -27,6 +27,7 @@ */ #import "WindowManager.h" +#import "MainWindow.h" @implementation WindowManager @@ -44,14 +45,21 @@ static WindowManager *instance = nil; return self; } -- (void)addWindow:(NSWindow*)win { +- (void)addWindow:(NSWindowController*)win { [_windows addObject:win]; - [win setDelegate:self]; } -- (void) windowWillClose:(NSNotification *) notification { - NSWindow *window = notification.object; - [_windows removeObject:window]; +- (void)closeWindow:(NSWindow*)win { + [_windows removeObject:win.windowController]; +} + +- (void)shutdown { + if(_windows.count > 0) { + NSWindowController *controller = _windows.firstObject; + MainWindow *win = (MainWindow*)controller.window; + [win saveWindowSize]; + } + [_windows removeAllObjects]; } @end diff --git a/ui/cocoa/appdelegate.m b/ui/cocoa/appdelegate.m index 82d9020..690053f 100644 --- a/ui/cocoa/appdelegate.m +++ b/ui/cocoa/appdelegate.m @@ -27,21 +27,26 @@ */ #import "AppDelegate.h" +#import "WindowManager.h" #import "toolkit.h" #import "menu.h" +#import "../common/app.h" + @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { ui_menu_init(); NSLog(@"toolkit applicationDidFinishLaunching"); - ui_cocoa_onstartup(); + uic_application_startup(NULL); } - (void)applicationWillTerminate:(NSNotification *)aNotification { NSLog(@"toolkit applicationWillTerminate"); - ui_cocoa_onexit(); + uic_application_exit(NULL); + [[WindowManager sharedWindowManager] shutdown]; + ui_app_save_settings(); } diff --git a/ui/cocoa/button.m b/ui/cocoa/button.m index 9a85451..dd1c559 100644 --- a/ui/cocoa/button.m +++ b/ui/cocoa/button.m @@ -64,7 +64,7 @@ UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs *args) { } -static void togglebutton_eventdata(id button, UiVar *var, void **eventdata, int *eventdatatype, int *value) { +static void togglebutton_eventdata(id button, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) { NSButton *btn = (NSButton*)button; NSControlStateValue state = btn.state; *value = (int)state; @@ -137,7 +137,7 @@ UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs *args) { return togglebutton_create(obj, args, NSButtonTypeSwitch); } -static void switch_eventdata(id button, UiVar *var, void **eventdata, int *eventdatatype, int *value) { +static void switch_eventdata(id button, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) { NSSwitch *btn = (NSSwitch*)button; NSControlStateValue state = btn.state; *value = (int)state; @@ -207,7 +207,7 @@ void ui_switch_set(UiInteger *i, int64_t value) { @end -static void radiobutton_eventdata(id button, UiVar *var, void **eventdata, int *eventdatatype, int *value) { +static void radiobutton_eventdata(id button, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) { if(var) { UiInteger *i = var->value; NSMutableArray *buttons = (__bridge NSMutableArray*)i->obj; diff --git a/ui/cocoa/text.m b/ui/cocoa/text.m index b2709d6..acbffed 100644 --- a/ui/cocoa/text.m +++ b/ui/cocoa/text.m @@ -73,7 +73,9 @@ UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) { } if(args->onchange || args->ontextchanged || args->onchange_action || args->ontextchanged_action) { - + TextAreaDelegate * tad = [[TextAreaDelegate alloc] init:obj var:var args:args]; + textview.delegate = tad; + objc_setAssociatedObject(textview, "delegate", tad, OBJC_ASSOCIATION_RETAIN); } return (__bridge void*)scrollview; @@ -379,7 +381,7 @@ void ui_textarea_remove(UiText *text, int begin, int end) { /* -------------------------- TextField -------------------------- */ -static void textfield_geteventdata(id sender, UiVar *var, void **eventdata, int *eventdatatype, int *value) { +static void textfield_geteventdata(id sender, UiVar *var, void **eventdata, UiEventType *eventdatatype, int *value) { } diff --git a/ui/cocoa/toolkit.h b/ui/cocoa/toolkit.h index 9a377b3..ab4c6da 100644 --- a/ui/cocoa/toolkit.h +++ b/ui/cocoa/toolkit.h @@ -51,7 +51,4 @@ @end -void ui_cocoa_onstartup(void); -void ui_cocoa_onopen(const char *file); -void ui_cocoa_onexit(void); diff --git a/ui/cocoa/toolkit.m b/ui/cocoa/toolkit.m index 66e4968..9a8e309 100644 --- a/ui/cocoa/toolkit.m +++ b/ui/cocoa/toolkit.m @@ -114,40 +114,10 @@ void ui_app_exit_on_shutdown(UiBool exitapp) { exit_on_shutdown = exitapp; } -void ui_cocoa_onstartup(void) { - UiEvent e; - e.obj = NULL; - e.window = NULL; - e.document = NULL; - e.eventdata = NULL; - e.intval = 0; - uic_application_startup(&e); -} - -void ui_cocoa_onopen(const char *file) { - UiEvent e; - e.obj = NULL; - e.window = NULL; - e.document = NULL; - e.eventdata = NULL; - e.intval = 0; - uic_application_open(&e); -} - -void ui_cocoa_onexit(void) { - UiEvent e; - e.obj = NULL; - e.window = NULL; - e.document = NULL; - e.eventdata = NULL; - e.intval = 0; - uic_application_exit(&e); -} - void ui_main(void) { main_thr_check("ui_main"); - NSApplicationMain(app_argc, app_argv); + NSApplicationMain(app_argc,app_argv); //[NSApp finishLaunching]; //[NSApp activateIgnoringOtherApps:YES]; //[NSApp run]; diff --git a/ui/cocoa/webview.m b/ui/cocoa/webview.m index 088ad5f..a4b4dae 100644 --- a/ui/cocoa/webview.m +++ b/ui/cocoa/webview.m @@ -52,7 +52,7 @@ UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs *args) { data->webview = (__bridge void*)webview; data->javascript = TRUE; data->zoom = 1; - value->value = value; + value->value = data; } } diff --git a/ui/cocoa/window.m b/ui/cocoa/window.m index b0259d2..459b649 100644 --- a/ui/cocoa/window.m +++ b/ui/cocoa/window.m @@ -41,6 +41,7 @@ #include "../common/menu.h" #include "../common/toolbar.h" #include "../common/object.h" +#include "../common/utils.h" #include @@ -50,19 +51,30 @@ static int window_default_height = 550; static int splitview_window_default_pos = -1; static UiBool splitview_window_use_prop = TRUE; +static void main_window_destroy(UiObject *obj) { + MainWindow *window = (__bridge MainWindow*)obj->wobj; + [window saveWindowSize]; + [[WindowManager sharedWindowManager] closeWindow:window]; +} + static UiObject* create_window(const char *title, BOOL simple, BOOL sidebar, BOOL splitview) { UiObject *obj = uic_object_new_toplevel(); - MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar withSplitview:splitview]; - [[WindowManager sharedWindowManager] addWindow:window]; - window.releasedWhenClosed = false; // TODO: we still need a cleanup strategy + int width = window_default_width; + int height = window_default_height; + if(!simple) { + ui_get_window_default_width(&width, &height); + } + + MainWindow *window = [[MainWindow alloc] init:obj withSidebar:sidebar withSplitview:splitview width:width height:height]; obj->wobj = (__bridge void*)window; + obj->destroy = main_window_destroy; MainWindowController *controller = [[MainWindowController alloc] initWithWindow:obj window:window]; window.windowController = controller; [window setNextResponder:(NSResponder*)controller]; - objc_setAssociatedObject(window, "windowcontroller", controller, OBJC_ASSOCIATION_RETAIN); + [[WindowManager sharedWindowManager] addWindow:controller]; return obj; } @@ -310,13 +322,15 @@ UiObject *ui_dialog_window_create(UiObject *parent, UiDialogWindowArgs *args) { NSWindowStyleMaskUtilityWindow) backing:NSBackingStoreBuffered defer:NO]; + NSWindowController *controller = [[NSWindowController alloc] initWithWindow:panel]; + panel.windowController = controller; panel.parent = (__bridge NSWindow*)parent->wobj; panel.obj = obj; panel.modal = args->modal; panel.onclick = args->onclick; panel.onclickdata = args->onclickdata; [panel center]; - [[WindowManager sharedWindowManager] addWindow:panel]; + [[WindowManager sharedWindowManager] addWindow:controller]; obj->wobj = (__bridge void*)panel; NSView *content = panel.contentView; diff --git a/ui/common/types.c b/ui/common/types.c index 72d5cd3..fb5f49d 100644 --- a/ui/common/types.c +++ b/ui/common/types.c @@ -760,6 +760,9 @@ void uic_range_save(UiRange *r) { void uic_generic_save(UiGeneric *g) { if(!g->obj) return; + // TODO: this leaks memory + // we can't just use get on Generic and ignore the result + // probably a separate save method is required g->get(g); } @@ -812,7 +815,7 @@ void uic_range_unbind(UiRange *r) { r->obj = NULL; } -void uic_list_unbind(UiList *l) { +void uic_list_unbind(UiList *l) { l->update = NULL; l->getselection = NULL; l->setselection = NULL; -- 2.52.0