mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
629 lines
23 KiB
C++
629 lines
23 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) 2019-2024 Chilledheart */
|
|
|
|
#include "gtk/yass_window.hpp"
|
|
|
|
#include <sstream>
|
|
|
|
#include <absl/flags/flag.h>
|
|
#include <glib/gi18n.h>
|
|
|
|
#include "cli/cli_connection_stats.hpp"
|
|
#include "core/utils.hpp"
|
|
#include "feature.h"
|
|
#include "freedesktop/utils.hpp"
|
|
#include "gtk/option_dialog.hpp"
|
|
#include "gtk/utils.hpp"
|
|
#include "gtk/yass.hpp"
|
|
#include "version.h"
|
|
|
|
#ifdef HAVE_APP_INDICATOR
|
|
extern "C" int app_indicator_init();
|
|
extern "C" void app_indicator_uninit();
|
|
#include "third_party/libappindicator/app-indicator.h"
|
|
#endif
|
|
|
|
YASSWindow* YASSWindow::window = nullptr;
|
|
|
|
YASSWindow::YASSWindow() : impl_(GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))) {
|
|
gtk_window_set_title(GTK_WINDOW(impl_), YASS_APP_PRODUCT_NAME);
|
|
gtk_window_set_default_size(GTK_WINDOW(impl_), 450, 420);
|
|
gtk_window_set_position(GTK_WINDOW(impl_), GTK_WIN_POS_CENTER);
|
|
gtk_window_set_resizable(GTK_WINDOW(impl_), false);
|
|
gtk_window_set_icon_name(GTK_WINDOW(impl_), "yass");
|
|
|
|
window = this;
|
|
|
|
auto show_callback = []() {
|
|
gdk_window_set_functions(gtk_widget_get_window(GTK_WIDGET(window->impl_)),
|
|
static_cast<GdkWMFunction>(GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE | GDK_FUNC_CLOSE));
|
|
};
|
|
g_signal_connect(G_OBJECT(impl_), "show", G_CALLBACK(show_callback), this);
|
|
|
|
auto hide_callback = []() { window->OnClose(); };
|
|
g_signal_connect(G_OBJECT(impl_), "hide", G_CALLBACK(hide_callback), this);
|
|
|
|
// vbox, hbox
|
|
GtkBox* vbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0));
|
|
GtkBox* hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 20));
|
|
GtkBox* left_box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0));
|
|
GtkGrid* right_panel_grid = GTK_GRID(gtk_grid_new());
|
|
|
|
// gtkmm's MenuBar/Menu/MenuItem is binded to model
|
|
GtkWidget* menubar;
|
|
GtkWidget* file_menu;
|
|
GtkWidget* help_menu;
|
|
GtkWidget* sep;
|
|
GtkWidget* file_menu_item;
|
|
GtkWidget* option_menu_item;
|
|
GtkWidget* exit_menu_item;
|
|
GtkWidget* help_menu_item;
|
|
GtkWidget* about_menu_item;
|
|
|
|
menubar = gtk_menu_bar_new();
|
|
|
|
file_menu = gtk_menu_new();
|
|
file_menu_item = gtk_menu_item_new_with_label(_("File"));
|
|
option_menu_item = gtk_menu_item_new_with_label(_("Option..."));
|
|
exit_menu_item = gtk_menu_item_new_with_label(_("Exit"));
|
|
|
|
sep = gtk_separator_menu_item_new();
|
|
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_menu_item), file_menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), option_menu_item);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), sep);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(file_menu), exit_menu_item);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file_menu_item);
|
|
|
|
auto option_callback = []() { window->OnOption(); };
|
|
g_signal_connect(G_OBJECT(option_menu_item), "activate", G_CALLBACK(option_callback), nullptr);
|
|
|
|
auto exit_callback = []() { window->close(); };
|
|
g_signal_connect(G_OBJECT(exit_menu_item), "activate", G_CALLBACK(exit_callback), nullptr);
|
|
|
|
help_menu = gtk_menu_new();
|
|
help_menu_item = gtk_menu_item_new_with_label(_("Help"));
|
|
about_menu_item = gtk_menu_item_new_with_label(_("About..."));
|
|
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_menu_item), help_menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(help_menu), about_menu_item);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), help_menu_item);
|
|
|
|
auto about_callback = []() { window->OnAbout(); };
|
|
g_signal_connect(G_OBJECT(about_menu_item), "activate", G_CALLBACK(about_callback), this);
|
|
|
|
gtk_box_pack_start(vbox, menubar, FALSE, FALSE, 0);
|
|
|
|
start_button_ = GTK_BUTTON(gtk_button_new());
|
|
gtk_button_set_label(start_button_, _("Start"));
|
|
|
|
gtk_widget_set_margin_top(GTK_WIDGET(start_button_), 30);
|
|
gtk_widget_set_margin_bottom(GTK_WIDGET(start_button_), 30);
|
|
|
|
stop_button_ = GTK_BUTTON(gtk_button_new());
|
|
gtk_button_set_label(stop_button_, _("Stop"));
|
|
gtk_widget_set_margin_top(GTK_WIDGET(stop_button_), 30);
|
|
gtk_widget_set_margin_bottom(GTK_WIDGET(stop_button_), 30);
|
|
|
|
auto start_callback = []() { window->OnStartButtonClicked(); };
|
|
|
|
g_signal_connect(G_OBJECT(start_button_), "clicked", G_CALLBACK(start_callback), nullptr);
|
|
|
|
auto stop_callback = []() { window->OnStopButtonClicked(); };
|
|
|
|
g_signal_connect(G_OBJECT(stop_button_), "clicked", G_CALLBACK(stop_callback), nullptr);
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), false);
|
|
|
|
gtk_container_add(GTK_CONTAINER(left_box), GTK_WIDGET(start_button_));
|
|
gtk_container_add(GTK_CONTAINER(left_box), GTK_WIDGET(stop_button_));
|
|
|
|
#if GTK_CHECK_VERSION(3, 12, 0)
|
|
gtk_widget_set_margin_start(GTK_WIDGET(left_box), 15);
|
|
gtk_widget_set_margin_end(GTK_WIDGET(left_box), 5);
|
|
#else
|
|
gtk_widget_set_margin_left(GTK_WIDGET(left_box), 15);
|
|
gtk_widget_set_margin_right(GTK_WIDGET(left_box), 5);
|
|
#endif
|
|
|
|
gtk_container_add(GTK_CONTAINER(hbox), GTK_WIDGET(left_box));
|
|
|
|
auto server_host_label_ = gtk_label_new(_("Server Host"));
|
|
auto server_sni_label_ = gtk_label_new(_("Server SNI"));
|
|
auto server_port_label_ = gtk_label_new(_("Server Port"));
|
|
auto username_label_ = gtk_label_new(_("Username"));
|
|
auto password_label_ = gtk_label_new(_("Password"));
|
|
auto method_label_ = gtk_label_new(_("Cipher/Method"));
|
|
auto local_host_label_ = gtk_label_new(_("Local Host"));
|
|
auto local_port_label_ = gtk_label_new(_("Local Port"));
|
|
auto doh_url_label_ = gtk_label_new(_("DNS over HTTPS URL"));
|
|
auto dot_host_label_ = gtk_label_new(_("DNS over TLS Host"));
|
|
auto timeout_label_ = gtk_label_new(_("Timeout"));
|
|
auto autostart_label_ = gtk_label_new(_("Auto Start"));
|
|
auto systemproxy_label_ = gtk_label_new(_("System Proxy"));
|
|
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(server_host_label_), 0, 0, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(server_sni_label_), 0, 1, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(server_port_label_), 0, 2, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(username_label_), 0, 3, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(password_label_), 0, 4, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(method_label_), 0, 5, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(local_host_label_), 0, 6, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(local_port_label_), 0, 7, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(doh_url_label_), 0, 8, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(dot_host_label_), 0, 9, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(timeout_label_), 0, 10, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(autostart_label_), 0, 11, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(systemproxy_label_), 0, 12, 1, 1);
|
|
|
|
server_host_ = GTK_ENTRY(gtk_entry_new());
|
|
server_sni_ = GTK_ENTRY(gtk_entry_new());
|
|
server_port_ = GTK_ENTRY(gtk_entry_new());
|
|
username_ = GTK_ENTRY(gtk_entry_new());
|
|
password_ = GTK_ENTRY(gtk_entry_new());
|
|
static constexpr const char* const method_names[] = {
|
|
#define XX(num, name, string) string,
|
|
CIPHER_METHOD_VALID_MAP(XX)
|
|
#undef XX
|
|
};
|
|
|
|
method_ = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
|
|
|
|
for (const char* method_name : method_names) {
|
|
gtk_combo_box_text_append_text(method_, method_name);
|
|
}
|
|
local_host_ = GTK_ENTRY(gtk_entry_new());
|
|
local_port_ = GTK_ENTRY(gtk_entry_new());
|
|
doh_url_ = GTK_ENTRY(gtk_entry_new());
|
|
dot_host_ = GTK_ENTRY(gtk_entry_new());
|
|
timeout_ = GTK_ENTRY(gtk_entry_new());
|
|
|
|
autostart_ = GTK_CHECK_BUTTON(gtk_check_button_new());
|
|
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(autostart_), Utils::GetAutoStart());
|
|
|
|
auto checked_auto_start_callback = []() { window->OnAutoStartClicked(); };
|
|
|
|
g_signal_connect(G_OBJECT(autostart_), "toggled", G_CALLBACK(checked_auto_start_callback), nullptr);
|
|
|
|
systemproxy_ = GTK_CHECK_BUTTON(gtk_check_button_new());
|
|
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(systemproxy_), Utils::GetSystemProxy());
|
|
|
|
auto checked_system_proxy_callback = []() { window->OnSystemProxyClicked(); };
|
|
|
|
g_signal_connect(G_OBJECT(systemproxy_), "toggled", G_CALLBACK(checked_system_proxy_callback), nullptr);
|
|
|
|
gtk_entry_set_visibility(password_, false);
|
|
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(server_host_), 1, 0, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(server_sni_), 1, 1, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(server_port_), 1, 2, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(username_), 1, 3, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(password_), 1, 4, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(method_), 1, 5, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(local_host_), 1, 6, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(local_port_), 1, 7, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(doh_url_), 1, 8, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(dot_host_), 1, 9, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(timeout_), 1, 10, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(autostart_), 1, 11, 1, 1);
|
|
gtk_grid_attach(right_panel_grid, GTK_WIDGET(systemproxy_), 1, 12, 1, 1);
|
|
|
|
#if GTK_CHECK_VERSION(3, 12, 0)
|
|
gtk_widget_set_margin_start(GTK_WIDGET(right_panel_grid), 5);
|
|
gtk_widget_set_margin_end(GTK_WIDGET(right_panel_grid), 5);
|
|
#else
|
|
gtk_widget_set_margin_left(GTK_WIDGET(right_panel_grid), 5);
|
|
gtk_widget_set_margin_right(GTK_WIDGET(right_panel_grid), 5);
|
|
#endif
|
|
|
|
gtk_widget_set_margin_top(GTK_WIDGET(hbox), 15);
|
|
gtk_widget_set_margin_bottom(GTK_WIDGET(hbox), 10);
|
|
#if GTK_CHECK_VERSION(3, 12, 0)
|
|
gtk_widget_set_margin_start(GTK_WIDGET(hbox), 20);
|
|
gtk_widget_set_margin_end(GTK_WIDGET(hbox), 20);
|
|
#else
|
|
gtk_widget_set_margin_left(GTK_WIDGET(hbox), 20);
|
|
gtk_widget_set_margin_right(GTK_WIDGET(hbox), 20);
|
|
#endif
|
|
|
|
gtk_container_add(GTK_CONTAINER(hbox), GTK_WIDGET(right_panel_grid));
|
|
|
|
gtk_box_pack_start(vbox, GTK_WIDGET(hbox), true, false, 0);
|
|
|
|
status_bar_ = GTK_STATUSBAR(gtk_statusbar_new());
|
|
gtk_statusbar_remove_all(status_bar_, 0);
|
|
gtk_statusbar_push(status_bar_, 0, _("READY"));
|
|
|
|
gtk_box_pack_start(vbox, GTK_WIDGET(status_bar_), true, false, 0);
|
|
|
|
gtk_container_add(GTK_CONTAINER(impl_), GTK_WIDGET(vbox));
|
|
|
|
LoadChanges();
|
|
|
|
gtk_widget_show_all(GTK_WIDGET(impl_));
|
|
|
|
#ifdef HAVE_APP_INDICATOR
|
|
if (app_indicator_init() == 0) {
|
|
LOG(INFO) << "libappindicator3 initialized";
|
|
CreateAppIndicator();
|
|
return;
|
|
} else {
|
|
LOG(WARNING) << "libappindicator3 not initialized";
|
|
}
|
|
#endif
|
|
CreateStatusIcon();
|
|
}
|
|
|
|
YASSWindow::~YASSWindow() {
|
|
if (tray_icon_) {
|
|
g_object_unref(G_OBJECT(tray_icon_));
|
|
tray_icon_ = nullptr;
|
|
}
|
|
#ifdef HAVE_APP_INDICATOR
|
|
if (tray_indicator_) {
|
|
g_object_unref(G_OBJECT(tray_indicator_));
|
|
tray_indicator_ = nullptr;
|
|
}
|
|
app_indicator_uninit();
|
|
#endif
|
|
}
|
|
|
|
void YASSWindow::CreateStatusIcon() {
|
|
// set try icon file
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
tray_icon_ = gtk_status_icon_new_from_icon_name("yass");
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
|
|
// set popup menu for tray icon
|
|
GtkWidget* sep;
|
|
GtkWidget* option_menu_item;
|
|
GtkWidget* exit_menu_item;
|
|
|
|
GtkWidget* tray_menu = gtk_menu_new();
|
|
option_menu_item = gtk_menu_item_new_with_label(_("Option..."));
|
|
exit_menu_item = gtk_menu_item_new_with_label(_("Exit"));
|
|
|
|
sep = gtk_separator_menu_item_new();
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), option_menu_item);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), sep);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), exit_menu_item);
|
|
|
|
auto option_callback = []() { window->OnOption(); };
|
|
g_signal_connect(G_OBJECT(option_menu_item), "activate", G_CALLBACK(option_callback), nullptr);
|
|
|
|
auto exit_callback = []() { window->close(); };
|
|
g_signal_connect(G_OBJECT(exit_menu_item), "activate", G_CALLBACK(exit_callback), nullptr);
|
|
|
|
gtk_widget_show_all(tray_menu);
|
|
|
|
// set tooltip
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
gtk_status_icon_set_tooltip_text(tray_icon_, _("Show"));
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
|
|
auto show_callback = []() {
|
|
window->show();
|
|
window->present();
|
|
};
|
|
g_signal_connect(G_OBJECT(tray_icon_), "activate", G_CALLBACK(show_callback), nullptr);
|
|
|
|
auto popup_callback = [](GtkStatusIcon* self, guint button, guint activate_time, gpointer popup_menu) {
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
gtk_menu_popup(GTK_MENU(popup_menu), nullptr, nullptr, gtk_status_icon_position_menu, self, button, activate_time);
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
};
|
|
g_signal_connect(G_OBJECT(tray_icon_), "popup-menu", G_CALLBACK(*popup_callback), tray_menu);
|
|
|
|
gtk_menu_attach_to_widget(GTK_MENU(tray_menu), GTK_WIDGET(impl_), nullptr);
|
|
}
|
|
|
|
#ifdef HAVE_APP_INDICATOR
|
|
void YASSWindow::CreateAppIndicator() {
|
|
// set try icon file
|
|
tray_indicator_ = G_OBJECT(app_indicator_new("it.gui.yass", "yass", APP_INDICATOR_CATEGORY_APPLICATION_STATUS));
|
|
app_indicator_set_status(APP_INDICATOR(tray_indicator_), APP_INDICATOR_STATUS_ACTIVE);
|
|
|
|
// set popup menu for tray icon
|
|
GtkWidget* show_menu_item;
|
|
GtkWidget* sep;
|
|
GtkWidget* option_menu_item;
|
|
GtkWidget* exit_menu_item;
|
|
|
|
GtkWidget* tray_menu = gtk_menu_new();
|
|
show_menu_item = gtk_menu_item_new_with_label(_("Show"));
|
|
option_menu_item = gtk_menu_item_new_with_label(_("Option..."));
|
|
exit_menu_item = gtk_menu_item_new_with_label(_("Exit"));
|
|
|
|
sep = gtk_separator_menu_item_new();
|
|
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), show_menu_item);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), option_menu_item);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), sep);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(tray_menu), exit_menu_item);
|
|
|
|
auto show_callback = []() {
|
|
window->show();
|
|
window->present();
|
|
};
|
|
g_signal_connect(G_OBJECT(show_menu_item), "activate", G_CALLBACK(show_callback), nullptr);
|
|
|
|
auto option_callback = []() { window->OnOption(); };
|
|
g_signal_connect(G_OBJECT(option_menu_item), "activate", G_CALLBACK(option_callback), nullptr);
|
|
|
|
auto exit_callback = []() { window->close(); };
|
|
g_signal_connect(G_OBJECT(exit_menu_item), "activate", G_CALLBACK(exit_callback), nullptr);
|
|
|
|
gtk_widget_show_all(tray_menu);
|
|
|
|
app_indicator_set_secondary_activate_target(APP_INDICATOR(tray_indicator_), GTK_WIDGET(show_menu_item));
|
|
app_indicator_set_menu(APP_INDICATOR(tray_indicator_), GTK_MENU(tray_menu));
|
|
}
|
|
#endif // HAVE_APP_INDICATOR
|
|
|
|
void YASSWindow::show() {
|
|
gtk_widget_show(GTK_WIDGET(impl_));
|
|
}
|
|
|
|
void YASSWindow::present() {
|
|
gtk_window_present(GTK_WINDOW(impl_));
|
|
}
|
|
|
|
void YASSWindow::close() {
|
|
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
|
if (tray_icon_) {
|
|
gtk_status_icon_set_visible(tray_icon_, FALSE);
|
|
}
|
|
G_GNUC_END_IGNORE_DEPRECATIONS
|
|
#ifdef HAVE_APP_INDICATOR
|
|
if (tray_indicator_) {
|
|
app_indicator_set_status(APP_INDICATOR(tray_indicator_), APP_INDICATOR_STATUS_PASSIVE);
|
|
}
|
|
#endif
|
|
gtk_window_close(GTK_WINDOW(impl_));
|
|
}
|
|
|
|
void YASSWindow::OnStartButtonClicked() {
|
|
gtk_widget_set_sensitive(GTK_WIDGET(start_button_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), false);
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_host_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_sni_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_port_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(username_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(password_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(method_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(local_host_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(local_port_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(doh_url_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(dot_host_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(timeout_), false);
|
|
|
|
mApp->OnStart();
|
|
}
|
|
|
|
void YASSWindow::OnStopButtonClicked() {
|
|
gtk_widget_set_sensitive(GTK_WIDGET(start_button_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), false);
|
|
|
|
mApp->OnStop();
|
|
}
|
|
|
|
void YASSWindow::OnAutoStartClicked() {
|
|
Utils::EnableAutoStart(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(autostart_)));
|
|
}
|
|
|
|
void YASSWindow::OnSystemProxyClicked() {
|
|
Utils::SetSystemProxy(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(systemproxy_)));
|
|
}
|
|
|
|
std::string YASSWindow::GetServerHost() {
|
|
return gtk_entry_get_text(server_host_);
|
|
}
|
|
|
|
std::string YASSWindow::GetServerSNI() {
|
|
return gtk_entry_get_text(server_sni_);
|
|
}
|
|
|
|
std::string YASSWindow::GetServerPort() {
|
|
return gtk_entry_get_text(server_port_);
|
|
}
|
|
|
|
std::string YASSWindow::GetUsername() {
|
|
return gtk_entry_get_text(username_);
|
|
}
|
|
|
|
std::string YASSWindow::GetPassword() {
|
|
return gtk_entry_get_text(password_);
|
|
}
|
|
|
|
std::string YASSWindow::GetMethod() {
|
|
gchar* active_method = gtk_combo_box_text_get_active_text(method_);
|
|
|
|
return make_unique_ptr_gfree(active_method).get();
|
|
}
|
|
|
|
std::string YASSWindow::GetLocalHost() {
|
|
return gtk_entry_get_text(local_host_);
|
|
}
|
|
|
|
std::string YASSWindow::GetLocalPort() {
|
|
return gtk_entry_get_text(local_port_);
|
|
}
|
|
|
|
std::string YASSWindow::GetDoHUrl() {
|
|
return gtk_entry_get_text(doh_url_);
|
|
}
|
|
|
|
std::string YASSWindow::GetDoTHost() {
|
|
return gtk_entry_get_text(dot_host_);
|
|
}
|
|
|
|
std::string YASSWindow::GetTimeout() {
|
|
return gtk_entry_get_text(timeout_);
|
|
}
|
|
|
|
std::string YASSWindow::GetStatusMessage() {
|
|
if (mApp->GetState() != YASSApp::STARTED) {
|
|
return mApp->GetStatus();
|
|
}
|
|
uint64_t sync_time = GetMonotonicTime();
|
|
uint64_t delta_time = sync_time - last_sync_time_;
|
|
if (delta_time > NS_PER_SECOND) {
|
|
uint64_t rx_bytes = net::cli::total_rx_bytes;
|
|
uint64_t tx_bytes = net::cli::total_tx_bytes;
|
|
rx_rate_ = static_cast<double>(rx_bytes - last_rx_bytes_) / delta_time * NS_PER_SECOND;
|
|
tx_rate_ = static_cast<double>(tx_bytes - last_tx_bytes_) / delta_time * NS_PER_SECOND;
|
|
last_sync_time_ = sync_time;
|
|
last_rx_bytes_ = rx_bytes;
|
|
last_tx_bytes_ = tx_bytes;
|
|
}
|
|
|
|
std::ostringstream ss;
|
|
ss << mApp->GetStatus();
|
|
ss << _(" tx rate: ");
|
|
HumanReadableByteCountBin(&ss, rx_rate_);
|
|
ss << "/s";
|
|
ss << _(" rx rate: ");
|
|
HumanReadableByteCountBin(&ss, tx_rate_);
|
|
ss << "/s";
|
|
|
|
return ss.str();
|
|
}
|
|
|
|
void YASSWindow::Started() {
|
|
UpdateStatusBar();
|
|
gtk_widget_set_sensitive(GTK_WIDGET(start_button_), false);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), true);
|
|
}
|
|
|
|
void YASSWindow::StartFailed() {
|
|
UpdateStatusBar();
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(start_button_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), false);
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_host_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_sni_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_port_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(username_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(password_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(method_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(local_host_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(local_port_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(doh_url_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(dot_host_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(timeout_), true);
|
|
|
|
GtkDialog* alert_dialog = GTK_DIALOG(gtk_message_dialog_new(impl_, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
|
|
GTK_BUTTONS_OK, "%s", mApp->GetStatus().c_str()));
|
|
|
|
gtk_dialog_run(GTK_DIALOG(alert_dialog));
|
|
gtk_widget_destroy(GTK_WIDGET(alert_dialog));
|
|
}
|
|
|
|
void YASSWindow::Stopped() {
|
|
UpdateStatusBar();
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(start_button_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(stop_button_), false);
|
|
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_host_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_sni_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(server_port_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(username_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(password_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(method_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(local_host_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(local_port_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(doh_url_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(dot_host_), true);
|
|
gtk_widget_set_sensitive(GTK_WIDGET(timeout_), true);
|
|
}
|
|
|
|
void YASSWindow::LoadChanges() {
|
|
auto server_host_str = absl::GetFlag(FLAGS_server_host);
|
|
auto server_sni_str = absl::GetFlag(FLAGS_server_sni);
|
|
auto server_port_str = std::to_string(absl::GetFlag(FLAGS_server_port));
|
|
auto username_str = absl::GetFlag(FLAGS_username);
|
|
auto password_str = absl::GetFlag(FLAGS_password);
|
|
uint32_t cipher_method = absl::GetFlag(FLAGS_method).method;
|
|
auto local_host_str = absl::GetFlag(FLAGS_local_host);
|
|
auto local_port_str = std::to_string(absl::GetFlag(FLAGS_local_port));
|
|
auto doh_url_str = absl::GetFlag(FLAGS_doh_url);
|
|
auto dot_host_str = absl::GetFlag(FLAGS_dot_host);
|
|
auto timeout_str = std::to_string(absl::GetFlag(FLAGS_connect_timeout));
|
|
|
|
gtk_entry_set_text(server_host_, server_host_str.c_str());
|
|
gtk_entry_set_text(server_sni_, server_sni_str.c_str());
|
|
gtk_entry_set_text(server_port_, server_port_str.c_str());
|
|
gtk_entry_set_text(username_, username_str.c_str());
|
|
gtk_entry_set_text(password_, password_str.c_str());
|
|
|
|
static const uint32_t method_ids[] = {
|
|
#define XX(num, name, string) num,
|
|
CIPHER_METHOD_VALID_MAP(XX)
|
|
#undef XX
|
|
};
|
|
unsigned int i;
|
|
for (i = 0; i < std::size(method_ids); ++i) {
|
|
if (cipher_method == method_ids[i])
|
|
break;
|
|
}
|
|
|
|
gtk_combo_box_set_active(GTK_COMBO_BOX(method_), i);
|
|
|
|
gtk_entry_set_text(local_host_, local_host_str.c_str());
|
|
gtk_entry_set_text(local_port_, local_port_str.c_str());
|
|
gtk_entry_set_text(doh_url_, doh_url_str.c_str());
|
|
gtk_entry_set_text(dot_host_, dot_host_str.c_str());
|
|
gtk_entry_set_text(timeout_, timeout_str.c_str());
|
|
}
|
|
|
|
void YASSWindow::UpdateStatusBar() {
|
|
std::string status_msg = GetStatusMessage();
|
|
if (last_status_msg_ == status_msg) {
|
|
return;
|
|
}
|
|
last_status_msg_ = status_msg;
|
|
gtk_statusbar_remove_all(status_bar_, 0);
|
|
gtk_statusbar_push(status_bar_, 0, last_status_msg_.c_str());
|
|
}
|
|
|
|
void YASSWindow::OnOption() {
|
|
OptionDialog option_dialog(_("YASS Option"), nullptr, true);
|
|
|
|
option_dialog.run();
|
|
}
|
|
|
|
void YASSWindow::OnAbout() {
|
|
GtkAboutDialog* about_dialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
|
|
const char* artists[] = {"macosicons.com", nullptr};
|
|
gtk_about_dialog_set_artists(about_dialog, artists);
|
|
const char* authors[] = {YASS_APP_COMPANY_NAME, nullptr};
|
|
gtk_about_dialog_set_authors(about_dialog, authors);
|
|
std::string comments = _("Last Change: ");
|
|
comments += YASS_APP_LAST_CHANGE;
|
|
comments += "\n";
|
|
comments += _("Enabled Feature: ");
|
|
comments += YASS_APP_FEATURES;
|
|
gtk_about_dialog_set_comments(about_dialog, comments.c_str());
|
|
gtk_about_dialog_set_copyright(about_dialog, YASS_APP_COPYRIGHT);
|
|
gtk_about_dialog_set_license_type(about_dialog, GTK_LICENSE_GPL_2_0_ONLY);
|
|
gtk_about_dialog_set_logo_icon_name(about_dialog, "yass");
|
|
gtk_about_dialog_set_program_name(about_dialog, YASS_APP_PRODUCT_NAME);
|
|
gtk_about_dialog_set_version(about_dialog, YASS_APP_PRODUCT_VERSION);
|
|
gtk_about_dialog_set_website(about_dialog, YASS_APP_WEBSITE);
|
|
gtk_about_dialog_set_website_label(about_dialog, _("official-site"));
|
|
gtk_window_set_position(GTK_WINDOW(about_dialog), GTK_WIN_POS_CENTER);
|
|
gtk_dialog_run(GTK_DIALOG(about_dialog));
|
|
gtk_widget_destroy(GTK_WIDGET(about_dialog));
|
|
}
|
|
|
|
void YASSWindow::OnClose() {
|
|
LOG(WARNING) << "Frame is closing ";
|
|
mApp->Exit();
|
|
}
|