2 weeks ago
implement window reference counting (WINUI3)
.hgignore | file | annotate | diff | comparison | revisions | |
make/vs/testapp/main.c | file | annotate | diff | comparison | revisions | |
ui/winui/toolkit.cpp | file | annotate | diff | comparison | revisions | |
ui/winui/window.cpp | file | annotate | diff | comparison | revisions |
--- a/.hgignore Wed Feb 26 17:06:56 2025 +0100 +++ b/.hgignore Wed Feb 26 17:39:03 2025 +0100 @@ -5,4 +5,5 @@ relre:^make/vs/packages/.* relre:^make/vs/.*vcxproj\.user relre:^make/xcode/toolkit/toolkit.xcodeproj/xcuserdata/.* -relre:^make/xcode/toolkit/toolkit.xcodeproj/project.xcworkspace/xcuserdata/.* \ No newline at end of file +relre:^make/xcode/toolkit/toolkit.xcodeproj/project.xcworkspace/xcuserdata/.* +relre:^ui/winui/Generated Files/.* \ No newline at end of file
--- a/make/vs/testapp/main.c Wed Feb 26 17:06:56 2025 +0100 +++ b/make/vs/testapp/main.c Wed Feb 26 17:39:03 2025 +0100 @@ -131,15 +131,29 @@ ui_show(dialog); } +UiObject *new_window; + +static void action_unref_newwindow(UiEvent *event, void *userdata) { + ui_object_unref(event->obj); + new_window = NULL; +} + void action_toolbar_newwindow(UiEvent *event, void *userdata) { + if (new_window) { + ui_show(new_window); + return; + } + UiObject *obj = ui_simple_window("New Window", NULL); + new_window = obj; + ui_object_ref(obj); ui_headerbar0(obj) { ui_headerbar_start(obj) { ui_button(obj, .label = "Open"); } ui_headerbar_end(obj) { - ui_button(obj, .label = "Test"); + ui_button(obj, .label = "Unref", .onclick = action_unref_newwindow); } }
--- a/ui/winui/toolkit.cpp Wed Feb 26 17:06:56 2025 +0100 +++ b/ui/winui/toolkit.cpp Wed Feb 26 17:39:03 2025 +0100 @@ -232,9 +232,13 @@ void ui_show(UiObject* obj) { if (obj->wobj) { - obj->wobj->window.Activate(); + if (!obj->wobj->window.Visible()) { + obj->wobj->window.Activate(); + obj->ref++; + } } else if(obj->widget && obj->widget->Show) { obj->widget->Show(); + obj->ref++; // TODO: should we check if the widget is already visible? } }
--- a/ui/winui/window.cpp Wed Feb 26 17:06:56 2025 +0100 +++ b/ui/winui/window.cpp Wed Feb 26 17:39:03 2025 +0100 @@ -63,6 +63,11 @@ UiWindow::UiWindow(winrt::Microsoft::UI::Xaml::Window& win) : window(win) {} +extern "C" static void ui_window_widget_destroy(UiObject *obj) { + obj->ref = 1; + obj->wobj->window.Close(); +} + UiObject* ui_window(const char* title, void* window_data) { UiObject* obj = ui_simple_window(title, window_data); @@ -178,17 +183,14 @@ obj->wobj = new UiWindow(window); ui_context_add_window_destructor(obj->ctx, obj->wobj); - window.Closed([obj](IInspectable const& sender, WindowEventArgs) { - if (obj->ctx->close_callback) { - UiEvent evt; - evt.obj = obj; - evt.document = obj->ctx->document; - evt.window = obj->window; - evt.eventdata = NULL; - evt.intval = 0; - obj->ctx->close_callback(&evt, obj->ctx->close_data); + window.Closed([obj](IInspectable const& sender, WindowEventArgs e) { + uic_context_prepare_close(obj->ctx); + obj->ref--; + if (obj->ref > 0) { + obj->wobj->window.AppWindow().Hide(); + e.Handled(true); } else { - ui_context_destroy(obj->ctx); + uic_object_destroy(obj); } });