Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gtk4: call gtk_widget_dispose_template #1028

Merged
merged 1 commit into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading