Skip to content

Commit

Permalink
gtk4: call gtk_widget_dispose_template
Browse files Browse the repository at this point in the history
- gtk4: cleanup opengl context

see #1027.
  • Loading branch information
Chilledheart committed Jun 28, 2024
1 parent c3d24f8 commit db9982c
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 27 deletions.
6 changes: 4 additions & 2 deletions src/gtk/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,12 @@ int YASSApp::ApplicationRun(int argc, char** argv) {
LOG(WARNING) << "app exited with code " << ret;
}

delete main_window_;

LOG(WARNING) << "Application exiting";

delete main_window_;
g_object_unref(impl_);
impl_ = nullptr;

// Memory leak clean up path
pango_cairo_font_map_set_default(nullptr);
cairo_debug_reset_static_data();
Expand Down
20 changes: 20 additions & 0 deletions src/gtk4/option_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ static void option_dialog_init(OptionGtkDialog* win) {
gtk_widget_init_template(GTK_WIDGET(win));
}

static void option_dialog_dispose(GObject* object) {
OptionGtkDialog* dialog = OPTION_DIALOG(object);
#if GTK_CHECK_VERSION(4, 8, 0)
gtk_widget_dispose_template(GTK_WIDGET(dialog), option_dialog_get_type());
#else
gtk_widget_unparent(dialog->tcp_keep_alive_check);
gtk_widget_unparent(dialog->tcp_keep_alive_cnt);
gtk_widget_unparent(dialog->tcp_keep_alive_idle_timeout);
gtk_widget_unparent(dialog->tcp_keep_alive_interval);
gtk_widget_unparent(dialog->enable_post_quantum_kyber);

gtk_widget_unparent(dialog->okay_button);
gtk_widget_unparent(dialog->cancel_button);
#endif

G_OBJECT_CLASS(option_dialog_parent_class)->dispose(object);
}

static void option_dialog_class_init(OptionGtkDialogClass* cls) {
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(cls), "/it/gui/yass/option_dialog.ui");

Expand All @@ -45,6 +63,8 @@ static void option_dialog_class_init(OptionGtkDialogClass* cls) {

gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(cls), OptionGtkDialog, okay_button);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(cls), OptionGtkDialog, cancel_button);

G_OBJECT_CLASS(cls)->dispose = option_dialog_dispose;
}

OptionGtkDialog* option_dialog_new(const gchar* title, GtkWindow* parent, GtkDialogFlags flags) {
Expand Down
7 changes: 4 additions & 3 deletions src/gtk4/option_dialog.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2021-2024 Chilledheart */
#ifndef OPTION_DIALOG
#define OPTION_DIALOG
#ifndef OPTION_DIALOG_H
#define OPTION_DIALOG_H

#include <gtk/gtk.h>

#include <string>

extern "C" {
#define OPTION_DIALOG_TYPE (option_dialog_get_type())
#define OPTION_DIALOG(dialog) (G_TYPE_CHECK_INSTANCE_CAST((dialog), OPTION_DIALOG_TYPE, OptionGtkDialog))
G_DECLARE_FINAL_TYPE(OptionGtkDialog, option_dialog, OPTIONGtk, DIALOG, GtkDialog)

OptionGtkDialog* option_dialog_new(const gchar* title, GtkWindow* parent, GtkDialogFlags flags);
Expand All @@ -32,4 +33,4 @@ class OptionDialog {
OptionGtkDialog* impl_;
}; // OptionDialog

#endif // OPTION_DIALOG
#endif // OPTION_DIALOG_H
43 changes: 32 additions & 11 deletions src/gtk4/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,33 +53,47 @@ static void about_activated(GSimpleAction* action, GVariant* parameter, gpointer
}

static void quit_activated(GSimpleAction* action, GVariant* parameter, gpointer app) {
LOG(WARNING) << "Quit Action is clicked";
YASSGtk_APP(app)->thiz->Exit();
}

static GActionEntry app_entries[] = {{"option", option_activated, NULL, NULL, NULL},
{"about", about_activated, NULL, NULL, NULL},
{"quit", quit_activated, NULL, NULL, NULL}};
static GActionEntry app_entries[] = {{"option", option_activated, nullptr, nullptr, nullptr},
{"about", about_activated, nullptr, nullptr, nullptr},
{"quit", quit_activated, nullptr, nullptr, nullptr}};

static void yass_app_startup(GApplication* app) {
const char* quit_accels[2] = {"<Ctrl>Q", NULL};
const char* quit_accels[2] = {"<Ctrl>Q", nullptr};

G_APPLICATION_CLASS(yass_app_parent_class)->startup(app);

g_action_map_add_action_entries(G_ACTION_MAP(app), app_entries, G_N_ELEMENTS(app_entries), app);
gtk_application_set_accels_for_action(GTK_APPLICATION(app), "app.quit", quit_accels);
}

static void yass_app_shutdown(GApplication* app) {
#if GLIB_VERSION_MIN_REQUIRED >= (G_ENCODE_VERSION(2, 78))
const char* quit_accels[2] = {"<Ctrl>Q", nullptr};

g_action_map_remove_action_entries(G_ACTION_MAP(app), app_entries, G_N_ELEMENTS(app_entries));
#endif

G_APPLICATION_CLASS(yass_app_parent_class)->shutdown(app);
}

static void yass_app_activate(GApplication* app) {
YASSGtk_APP(app)->thiz->OnActivate();
}

static void yass_app_class_init(YASSGtkAppClass* cls) {
G_APPLICATION_CLASS(cls)->startup = yass_app_startup;
G_APPLICATION_CLASS(cls)->shutdown = yass_app_shutdown;
G_APPLICATION_CLASS(cls)->activate = yass_app_activate;
}

YASSGtkApp* yass_app_new(void) {
return YASSGtk_APP(g_object_new(yass_app_get_type(), "application-id", kAppId, NULL));
auto app = YASSGtk_APP(g_object_new(yass_app_get_type(), "application-id", kAppId, nullptr));
g_set_application_name(kAppName);
return app;
}
} // extern "C"

Expand Down Expand Up @@ -144,7 +158,6 @@ int main(int argc, const char** argv) {

YASSApp::YASSApp() : impl_(G_APPLICATION(yass_app_new())), idle_source_(g_timeout_source_new(200)) {
YASSGtk_APP(impl_)->thiz = this;
g_set_application_name(kAppName);

auto idle_handler = [](gpointer user_data) -> gboolean {
if (!mApp) {
Expand Down Expand Up @@ -211,16 +224,24 @@ int YASSApp::ApplicationRun(int argc, char** argv) {

if (ret) {
LOG(WARNING) << "app exited with code " << ret;
} else {
LOG(WARNING) << "Application exiting";
}

#if 0
LOG(WARNING) << "Application exiting";

delete main_window_;
g_object_unref(impl_);
impl_ = nullptr;

// Cleanup opengl's context prior to pango cleanup
if (auto context = gdk_gl_context_get_current()) {
gdk_display_close(gdk_gl_context_get_display(context));
gdk_gl_context_clear_current();
}

// Memory leak clean up path
pango_cairo_font_map_set_default(nullptr);
cairo_debug_reset_static_data();
FcFini();
#endif

PrintMallocStats();

Expand All @@ -235,7 +256,7 @@ void YASSApp::Exit() {
g_source_destroy(idle_source_);
g_source_destroy(exit_int_source_);
g_source_destroy(exit_term_source_);
g_application_quit(G_APPLICATION(impl_));
main_window_->close();
}

void YASSApp::OnIdle() {
Expand Down
57 changes: 46 additions & 11 deletions src/gtk4/yass_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,35 @@ static void yass_window_init(YASSGtkWindow* win) {
g_object_unref(builder);
}

static void yass_window_dispose(GObject* object) {
YASSGtkWindow* window = YASS_WINDOW(object);
#if GTK_CHECK_VERSION(4, 8, 0)
gtk_widget_dispose_template(GTK_WIDGET(window), yass_window_get_type());
#else
gtk_widget_unparent(window->gears);

gtk_widget_unparent(window->status_bar);

gtk_widget_unparent(window->start_button);
gtk_widget_unparent(window->stop_button);

gtk_widget_unparent(window->server_host);
gtk_widget_unparent(window->server_sni);
gtk_widget_unparent(window->server_port);
gtk_widget_unparent(window->username);
gtk_widget_unparent(window->password);
gtk_widget_unparent(window->method);
gtk_widget_unparent(window->local_host);
gtk_widget_unparent(window->local_port);
gtk_widget_unparent(window->doh_url);
gtk_widget_unparent(window->dot_host);
gtk_widget_unparent(window->timeout);
gtk_widget_unparent(window->autostart);
gtk_widget_unparent(window->systemproxy);
#endif
G_OBJECT_CLASS(yass_window_parent_class)->dispose(object);
}

static void yass_window_class_init(YASSGtkWindowClass* cls) {
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(cls), "/it/gui/yass/yass_window.ui");
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(cls), YASSGtkWindow, gears);
Expand All @@ -82,22 +111,22 @@ static void yass_window_class_init(YASSGtkWindowClass* cls) {
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(cls), YASSGtkWindow, timeout);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(cls), YASSGtkWindow, autostart);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(cls), YASSGtkWindow, systemproxy);

G_OBJECT_CLASS(cls)->dispose = yass_window_dispose;
}

YASSGtkWindow* yass_window_new(YASSGtkApp* app) {
return YASSGtk_WINDOW(g_object_new(yass_window_get_type(), "application", app, NULL));
auto window = YASSGtk_WINDOW(g_object_new(yass_window_get_type(), "application", app, nullptr));
gtk_window_set_resizable(GTK_WINDOW(window), false);
gtk_window_set_icon_name(GTK_WINDOW(window), "yass");
return window;
}

} // extern "C"

YASSWindow::YASSWindow(GApplication* app) : impl_(yass_window_new(YASSGtk_APP(app))) {
#if 0
gtk_window_set_position(GTK_WINDOW(impl_), GTK_WIN_POS_CENTER);
#endif
gtk_window_set_resizable(GTK_WINDOW(impl_), false);
gtk_window_set_icon_name(GTK_WINDOW(impl_), "yass");

static YASSWindow* window = this;
YASSWindow::YASSWindow(GApplication* app) : app_(app), impl_(yass_window_new(YASSGtk_APP(app))) {
static YASSWindow* window;
window = this;

// forward to hide event
gtk_window_set_hide_on_close(GTK_WINDOW(impl_), TRUE);
Expand Down Expand Up @@ -148,7 +177,9 @@ YASSWindow::YASSWindow(GApplication* app) : impl_(yass_window_new(YASSGtk_APP(ap
LoadChanges();
}

YASSWindow::~YASSWindow() = default;
YASSWindow::~YASSWindow() {
gtk_window_destroy(GTK_WINDOW(impl_));
}

void YASSWindow::show() {
gtk_widget_set_visible(GTK_WIDGET(impl_), true);
Expand All @@ -158,6 +189,10 @@ void YASSWindow::present() {
gtk_window_present(GTK_WINDOW(impl_));
}

void YASSWindow::close() {
gtk_application_remove_window(GTK_APPLICATION(app_), GTK_WINDOW(impl_));
}

void YASSWindow::OnStartButtonClicked() {
gtk_widget_set_sensitive(impl_->start_button, false);
gtk_widget_set_sensitive(impl_->stop_button, false);
Expand Down Expand Up @@ -378,6 +413,6 @@ void YASSWindow::UpdateStatusBar() {
}

void YASSWindow::OnClose() {
LOG(WARNING) << "Frame is closing ";
LOG(WARNING) << "Frame is closing";
mApp->Exit();
}
3 changes: 3 additions & 0 deletions src/gtk4/yass_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

extern "C" {
#define YASS_WINDOW_TYPE (yass_window_get_type())
#define YASS_WINDOW(window) (G_TYPE_CHECK_INSTANCE_CAST((window), YASS_WINDOW_TYPE, YASSGtkWindow))
G_DECLARE_FINAL_TYPE(YASSGtkWindow, yass_window, YASSGtk, WINDOW, GtkApplicationWindow)

YASSGtkWindow* yass_window_new(YASSGtkApp* app);
Expand All @@ -25,12 +26,14 @@ class YASSWindow {
YASSGtkWindow* impl() { return impl_; }

private:
GApplication* app_;
YASSGtkWindow* impl_;
std::string last_status_msg_;

public:
void show();
void present();
void close();

void OnStartButtonClicked();
void OnStopButtonClicked();
Expand Down

0 comments on commit db9982c

Please sign in to comment.