From 14fd4f82f794783575b9c3f7d810f0d03abb053c Mon Sep 17 00:00:00 2001 From: N0VA Date: Sun, 4 Jan 2026 17:30:20 +0100 Subject: [PATCH] GTK4 --- meson.build | 26 +-- src/device_settings.ui | 71 +++--- src/main.c | 3 +- src/remote_list.ui | 82 +------ src/settings.ui | 229 ++++-------------- src/teleport-app.c | 68 +++--- src/teleport-app.h | 4 +- src/teleport-remote-device.c | 313 +++++-------------------- src/teleport-remote-device.h | 5 +- src/teleport-window.c | 142 ++++++----- src/teleport-window.h | 4 +- src/window.ui | 442 +++++++++++------------------------ 12 files changed, 390 insertions(+), 999 deletions(-) diff --git a/meson.build b/meson.build index 3269e19..e956146 100644 --- a/meson.build +++ b/meson.build @@ -146,31 +146,15 @@ endif add_project_arguments(common_flags + compiler_flags, language: 'c') -glib_dep = dependency('glib-2.0', version: '>= 2.43.4') -gtk_dep = dependency('gtk+-3.0', version: '>= 3.22.0') - -libhandy_dep = dependency('libhandy-0.0', version: '>= 0.0.9', required: false) -if not libhandy_dep.found() - libhandy = subproject( - 'libhandy', - default_options: [ - 'examples=false', - 'glade_catalog=disabled', - 'introspection=disabled', - 'static=true', - 'tests=false', - 'vapi=false', - ] - ) - libhandy_dep = libhandy.get_variable('libhandy_dep') -endif - +glib_dep = dependency('glib-2.0', version: '>= 2.66') +gtk_dep = dependency('gtk4', version: '>= 4.0.0') +libadwaita_dep = dependency('libadwaita-1', version: '>= 1.0.0') teleport_deps = [ glib_dep, gtk_dep, - libhandy_dep, - dependency('gio-2.0', version: '>= 2.43.4'), + libadwaita_dep, + dependency('gio-2.0', version: '>= 2.66'), dependency('libsoup-2.4'), dependency('avahi-client'), cc.find_library('m', required: true) diff --git a/src/device_settings.ui b/src/device_settings.ui index 6e136e0..d0f45d7 100644 --- a/src/device_settings.ui +++ b/src/device_settings.ui @@ -1,53 +1,40 @@ - + - - - - - True - 10 - 6 + + + + + 10 + 10 + 10 + 10 + vertical + 6 - True Device name - GTK_ALIGN_START - 6 + start - - 0 - 0 - 1 - 1 - - - True + + 6 + + + True + + + + + Rename + + + - - 0 - 1 - 1 - 1 - - - - - True - Rename - - - - 1 - 1 - 1 - 1 - - + - + \ No newline at end of file diff --git a/src/main.c b/src/main.c index 729ac7f..404ea85 100644 --- a/src/main.c +++ b/src/main.c @@ -16,12 +16,13 @@ * along with this program. If not, see . */ -#include +#include #include "teleport-app.h" int main (int argc, char *argv[]) { + adw_init (); return g_application_run (G_APPLICATION (teleport_app_new ()), argc, argv); } diff --git a/src/remote_list.ui b/src/remote_list.ui index 5054fa3..de9a396 100644 --- a/src/remote_list.ui +++ b/src/remote_list.ui @@ -1,75 +1,15 @@ - + - - + \ No newline at end of file diff --git a/src/settings.ui b/src/settings.ui index 0f62021..4731f66 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -1,128 +1,73 @@ - - + - False - + - True - False vertical - 12 + 12 + 12 + 12 + 12 + 12 - - True - False + + vertical + 6 - True - False - 6 Save received files in: 0 - - 0 - 0 - - - True - False - select-folder - Choose download dir + + Choose download dir - - 0 - 1 - + + + + + vertical + 6 - False - 18 - 6 + 6 Automatically enable Teleport on these networks: 0 - - 0 - 2 - 2 - - False - none + none + - True - True False - - True - False - 12 - 6 - 12 - 6 - 6 - 6 - 16 + + 12 + 6 + 6 + 6 + 12 - True - False True o2-WLAN09 - True 0 - - 0 - 0 - - - True - False - center - True - - - 35 - True - True - False - - - True - False - window-close-symbolic - - - - - - 0 - 0 - - + + window-close-symbolic - - 1 - 0 - @@ -130,128 +75,52 @@ - True - True False - - True - False - 12 - 6 - 12 - 6 - 6 - 6 - 16 + + 12 + 6 + 6 + 6 + 12 - True - False True Add Network - True 0 - - 0 - 0 - - - True - False - center - True - - - 35 - True - True - False - - - True - False - list-add-symbolic - - - - - - 0 - 0 - - + + list-add-symbolic - - 1 - 0 - - - 0 - 4 - 2 - - - - - - - - - - - - - - - False - True - 0 - - True - False - 6 + 6 - - False - True - 1 - - - True - True - True + app.about - _About Teleport + About Teleport + - - False - True - 2 - - + - + \ No newline at end of file diff --git a/src/teleport-app.c b/src/teleport-app.c index 51296ed..f7a0f3b 100644 --- a/src/teleport-app.c +++ b/src/teleport-app.c @@ -1,22 +1,22 @@ /* teleport-app.c - * + * * Copyright 2017 Julian Sparber - * - * Teleport is free software: you can redistribute it and/or modify + * + * Teleport is free software: you can redistribute and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -84,13 +84,13 @@ typedef struct struct _TeleportApp { - GtkApplication parent; + AdwApplication parent; /*< private >*/ TeleportAppPrivate *priv; }; -G_DEFINE_TYPE_WITH_PRIVATE (TeleportApp, teleport_app, GTK_TYPE_APPLICATION); +G_DEFINE_TYPE_WITH_PRIVATE (TeleportApp, teleport_app, ADW_TYPE_APPLICATION); static void @@ -231,7 +231,7 @@ open_file_callback (GSimpleAction *simple, g_variant_get_string (g_variant_get_child_value (parameter, 3), NULL), g_variant_get_string (g_variant_get_child_value (parameter, 2), NULL)); - gtk_show_uri_on_window (NULL, g_filename_to_uri(path, NULL, NULL), GDK_CURRENT_TIME, NULL); + gtk_show_uri (NULL, g_filename_to_uri(path, NULL, NULL), GDK_CURRENT_TIME); } void @@ -251,9 +251,6 @@ create_user_notification (const char *file_name, const int file_size, const char g_notification_set_priority (notification, G_NOTIFICATION_PRIORITY_HIGH); g_application_send_notification ((GApplication *) mainApplication, NULL, notification); g_object_unref (notification); - //the example says I have to unref it but it gives a critival error - //https://developer.gnome.org/glib/stable/gvariant-format-strings.html - //g_variant_unref (target); } void @@ -289,7 +286,6 @@ mainLoopRemovePeerCallback (gpointer peer) { GtkWidget *window = priv->window; update_remote_device_list_remove((TeleportWindow *) window, (Peer *) peer); - //if (teleport_peer_get_number (priv->peerList) == 0) if (teleport_peer_get_number (priv->peerList) == 0) teleport_show_no_device_message (TELEPORT_WINDOW (window), TRUE); return G_SOURCE_REMOVE; @@ -307,7 +303,6 @@ callback_remove_peer (GObject *instance, Peer *peer, gpointer window) { void callback_notify_user (GObject *instance, gchar *name, gpointer window) { - //create_user_notification("icon.png", 2000, "Mark's laptop"); } GSettings * @@ -374,10 +369,10 @@ teleport_app_startup (GApplication *app) { /* CSS style */ provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ()); gtk_css_provider_load_from_resource (GTK_CSS_PROVIDER (provider), - "com/frac_tion/teleport/style.css"); - gtk_style_context_add_provider_for_screen (gdk_screen_get_default(), - provider, - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + "/com/frac_tion/teleport/style.css"); + gtk_style_context_add_provider_for_display (gdk_display_get_default(), + provider, + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_object_unref (provider); /* PeerList */ @@ -398,15 +393,12 @@ teleport_app_activate (GApplication *app) { TeleportAppPrivate *priv; priv = mainApplication->priv; - gtk_widget_show (priv->window); gtk_window_present (GTK_WINDOW (priv->window)); } static void teleport_app_finalize (GObject *object) { - /*TeleportAppPrivate priv = mainApplication->priv; - g_clear_object (&priv->settings);*/ G_OBJECT_CLASS (teleport_app_parent_class)->finalize (object); } @@ -436,45 +428,39 @@ teleport_app_show_about (GSimpleAction *simple, gpointer user_data) { TeleportAppPrivate *priv = TELEPORT_APP (user_data)->priv; - char *copyright; - GDateTime *date; + g_autofree char *copyright = NULL; + g_autoptr(GDateTime) date = g_date_time_new_now_local (); int created_year = 2017; - static const gchar *authors[] = { + static const char *developers[] = { "Julian Sparber ", NULL }; - static const gchar *artists[] = { + static const char *artists[] = { "Tobias Bernard ", NULL }; - date = g_date_time_new_now_local (); - if (g_date_time_get_year (date) <= created_year) { - copyright = g_strdup_printf (("Copyright \xC2\xA9 %d " - "The Teleport authors"), created_year); + copyright = g_strdup_printf ("Copyright \xC2\xA9 %d The Teleport authors", created_year); } else { - copyright = g_strdup_printf (("Copyright \xC2\xA9 %d\xE2\x80\x93%d " - "The Telport authors"), created_year, g_date_time_get_year (date)); + copyright = g_strdup_printf ("Copyright \xC2\xA9 %d\xE2\x80\x93%d The Teleport authors", created_year, g_date_time_get_year (date)); } - gtk_show_about_dialog (GTK_WINDOW (priv->window), - "program-name", ("Teleport"), + adw_show_about_dialog (priv->window, + "application-name", "Teleport", "version", VERSION, "copyright", copyright, "license-type", GTK_LICENSE_AGPL_3_0, - "authors", authors, + "developers", developers, "artists", artists, - "logo-icon-name", "com.frac_tion.teleport", - "translator-credits", ("translator-credits"), + "application-icon", "com.frac_tion.teleport", + "translator-credits", "translator-credits", NULL); - g_free (copyright); - g_date_time_unref (date); } @@ -485,7 +471,7 @@ teleport_app_quit (GSimpleAction *simple, { TeleportAppPrivate *priv = TELEPORT_APP (user_data)->priv; - gtk_widget_destroy (priv->window); + gtk_window_destroy (GTK_WINDOW (priv->window)); } TeleportApp * @@ -504,6 +490,4 @@ teleport_app_init (TeleportApp *app) { priv->settings = g_settings_new ("com.frac_tion.teleport"); init_settings (priv->settings); -} - - +} \ No newline at end of file diff --git a/src/teleport-app.h b/src/teleport-app.h index 73b9b04..b699288 100644 --- a/src/teleport-app.h +++ b/src/teleport-app.h @@ -19,12 +19,12 @@ #ifndef __TELEPORT_APP_H #define __TELEPORT_APP_H -#include +#include #include "teleport-peer.h" #define TELEPORT_APP_TYPE (teleport_app_get_type ()) -G_DECLARE_FINAL_TYPE (TeleportApp, teleport_app, TELEPORT, APP, GtkApplication) +G_DECLARE_FINAL_TYPE (TeleportApp, teleport_app, TELEPORT, APP, AdwApplication) TeleportApp *teleport_app_new (void); diff --git a/src/teleport-remote-device.c b/src/teleport-remote-device.c index 208bf7c..c56b3d5 100644 --- a/src/teleport-remote-device.c +++ b/src/teleport-remote-device.c @@ -16,59 +16,32 @@ * along with this program. If not, see . */ -#include +#include #include "teleport-remote-device.h" #include "teleport-peer.h" #include "teleport-server.h" -enum { - TARGET_INT32, - TARGET_STRING, - TARGET_URIS, - TARGET_ROOTWIN -}; - enum -{ - PROP_0, - PROP_PEER, - LAST_PROP +{ + PROP_0, + PROP_PEER, + LAST_PROP }; -/* datatype (string), restrictions on DnD (GtkTargetFlags), datatype (int) */ -static GtkTargetEntry target_list[] = { - //{ "INTEGER", 0, TARGET_INT32 }, - //{ "STRING", 0, TARGET_STRING }, - //{ "text/plain", 0, TARGET_STRING }, - { "text/uri-list", 0, TARGET_URIS } - //{ "application/octet-stream", 0, TARGET_STRING }, - //{ "application/x-rootwindow-drop", 0, TARGET_ROOTWIN } -}; - -static guint n_targets = G_N_ELEMENTS (target_list); - struct _TeleportRemoteDevice { - GtkFrame parent; - GtkWidget *remote_device_row; - GtkWidget *device_name; + AdwActionRow parent; GtkWidget *send_btn; /* data */ Peer *peer; }; -G_DEFINE_TYPE (TeleportRemoteDevice, teleport_remote_device, GTK_TYPE_FRAME) - - /* - * GObject overrides - */ +G_DEFINE_TYPE (TeleportRemoteDevice, teleport_remote_device, ADW_TYPE_ACTION_ROW) static void teleport_remote_device_finalize (GObject *object) { - //TeleportRemoteDevice *self = TELEPORT_REMOTE_DEVICE (object); - G_OBJECT_CLASS (teleport_remote_device_parent_class)->finalize (object); } @@ -127,11 +100,6 @@ teleport_remote_device_class_init (TeleportRemoteDeviceClass *klass) object_class->get_property = teleport_remote_device_get_property; object_class->set_property = teleport_remote_device_set_property; - /** - * TeleportRemoteDevice::peer: - * - * The peer that this row represents, or %NULL. - */ g_object_class_install_property (object_class, PROP_PEER, g_param_spec_pointer ("peer", @@ -139,212 +107,95 @@ teleport_remote_device_class_init (TeleportRemoteDeviceClass *klass) "The peer that this row represents", G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /*g_param_spec_object ("peer", - "Task of the row", - "The task that this row represents", - (Peer *), - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - */ - gtk_widget_class_set_template_from_resource (widget_class, "/com/frac_tion/teleport/remote_list.ui"); - gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, remote_device_row); - gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, device_name); gtk_widget_class_bind_template_child (widget_class, TeleportRemoteDevice, send_btn); } +static void +on_file_chooser_response (GtkNativeDialog *dialog, + int response, + gpointer user_data) +{ + Peer *device = user_data; + + if (response == GTK_RESPONSE_ACCEPT) + { + g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); + g_autofree char *filename = g_file_get_path (file); + if (filename) + { + g_print("Chosen file is %s\n", filename); + teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), g_strdup(filename), device->ip); + } + } + + g_object_unref (dialog); +} + static void open_file_picker(GtkButton *btn, Peer *device) { GtkFileChooserNative *dialog; - GtkWidget * window; - GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; - gint res; + GtkRoot *root; + g_print("Open file chooser for submitting a file to %s with Address %s\n", device->name, device->ip); - window = gtk_widget_get_toplevel (GTK_WIDGET (btn)); - if (gtk_widget_is_toplevel (window)) + root = gtk_widget_get_root (GTK_WIDGET (btn)); + if (GTK_IS_WINDOW (root)) { dialog = gtk_file_chooser_native_new ("Open File", - GTK_WINDOW(window), - action, + GTK_WINDOW (root), + GTK_FILE_CHOOSER_ACTION_OPEN, ("_Open"), ("_Cancel")); - res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (dialog)); - if (res == GTK_RESPONSE_ACCEPT) - { - char *filename; - GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); - filename = gtk_file_chooser_get_filename (chooser); - g_print("Choosen file is %s\n", filename); - g_object_unref (dialog); - teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), filename, device->ip); - g_free (filename); - } - else - { - g_object_unref (dialog); - } - + g_signal_connect (dialog, "response", G_CALLBACK (on_file_chooser_response), device); + gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog)); } } - static void -send_file_to_device (gchar *uri, gpointer data) +send_file_to_device (GFile *file, Peer *device) { - Peer *device = (Peer *) data; - GFile *file = g_file_new_for_uri (uri); - gchar *filename = NULL; + g_autofree gchar *filename = g_file_get_path (file); if (g_file_query_exists (file, NULL)) { - filename = g_file_get_path (file); teleport_server_add_route (g_compute_checksum_for_string (G_CHECKSUM_SHA256, filename, -1), g_strdup(filename), device->ip); - g_free (filename); } else { - g_print ("File doesn't exist: %s\n", uri); + g_print ("File doesn't exist: %s\n", filename); } - g_object_unref(file); } - -static void -drag_data_received_handl -(GtkWidget *widget, GdkDragContext *context, gint x, gint y, - GtkSelectionData *selection_data, guint target_type, guint time, - gpointer data) -{ - glong *_idata; - gchar *_sdata; - gchar **uris; - - gboolean dnd_success = FALSE; - gboolean delete_selection_data = FALSE; - - /* Deal with what we are given from source */ - if((selection_data != NULL) && (gtk_selection_data_get_length(selection_data) >= 0)) - { - if (gdk_drag_context_get_suggested_action(context) == GDK_ACTION_ASK) - { - /* Ask the user to move or copy, then set the context action. */ - } - - if (gdk_drag_context_get_suggested_action(context) == GDK_ACTION_MOVE) - delete_selection_data = TRUE; - - /* Check that we got the format we can use */ - switch (target_type) - { - case TARGET_INT32: - _idata = (glong*)gtk_selection_data_get_data(selection_data); - g_print ("integer: %ld", *_idata); - dnd_success = TRUE; - break; - - case TARGET_STRING: - _sdata = (gchar*)gtk_selection_data_get_data(selection_data); - g_print ("string: %s", _sdata); - dnd_success = TRUE; - break; - - case TARGET_URIS: - uris = gtk_selection_data_get_uris(selection_data); - if (uris != NULL && uris[1] == NULL) { - send_file_to_device (uris[0], data); - dnd_success = TRUE; - } - break; - - default: - g_print ("Something bad!"); - } - } - - if (dnd_success == FALSE) - { - g_print ("DnD data transfer failed!\n"); - g_print ("You can not drag more then one file!\n"); - } - - gtk_drag_finish (context, dnd_success, delete_selection_data, time); -} - -/* Emitted when a drag is over the destination */ static gboolean -drag_motion_handl -(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint t, - gpointer user_data) +on_drop (GtkDropTarget *target, + const GValue *value, + double x, + double y, + gpointer user_data) { - // Fancy stuff here. This signal spams the console something horrible. - //const gchar *name = gtk_widget_get_name (widget); - //g_print ("%s: drag_motion_handl\n", name); - return FALSE; -} - -/* Emitted when a drag leaves the destination */ -static void -drag_leave_handl -(GtkWidget *widget, GdkDragContext *context, guint time, gpointer user_data) -{ -} - -/* Emitted when the user releases (drops) the selection. It should check that - * the drop is over a valid part of the widget (if its a complex widget), and - * itself to return true if the operation should continue. Next choose the - * target type it wishes to ask the source for. Finally call gtk_drag_get_data - * which will emit "drag-data-get" on the source. */ -static gboolean -drag_drop_handl -(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, - gpointer user_data) -{ - gboolean is_valid_drop_site; - GdkAtom target_type; - - /* Check to see if (x,y) is a valid drop site within widget */ - is_valid_drop_site = TRUE; - - /* If the source offers a target */ - if (gdk_drag_context_list_targets (context)) + TeleportRemoteDevice *self = user_data; + if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST)) { - /* Choose the best target type */ - target_type = GDK_POINTER_TO_ATOM - (g_list_nth_data (gdk_drag_context_list_targets(context), TARGET_INT32)); - - - /* Request the data from the source. */ - gtk_drag_get_data - ( - widget, /* will receive 'drag-data-received' signal */ - context, /* represents the current state of the DnD */ - target_type, /* the target type we want */ - time /* time stamp */ - ); + GSList *list = g_value_get_boxed (value); + for (GSList *l = list; l != NULL; l = l->next) + { + send_file_to_device (G_FILE (l->data), self->peer); + } + return TRUE; } - /* No target offered by source => error */ - else - { - is_valid_drop_site = FALSE; - } - - return is_valid_drop_site; + return FALSE; } static void teleport_remote_device_init (TeleportRemoteDevice *self) { + GtkDropTarget *target; + gtk_widget_init_template (GTK_WIDGET (self)); - /* Make the widget a DnD destination. */ - gtk_drag_dest_set - ( - GTK_WIDGET (self->remote_device_row), /* widget that will accept a drop */ - GTK_DEST_DEFAULT_MOTION /* default actions for dest on DnD */ - | GTK_DEST_DEFAULT_HIGHLIGHT, - target_list, /* lists of target to support */ - n_targets, /* size of list */ - GDK_ACTION_COPY /* what to do with data after dropped */ - ); + target = gtk_drop_target_new (GDK_TYPE_FILE_LIST, GDK_ACTION_COPY); + g_signal_connect (target, "drop", G_CALLBACK (on_drop), self); + gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (target)); } GtkWidget* @@ -355,17 +206,8 @@ teleport_remote_device_new (Peer *peer) NULL); } -/** - * teleport_remote_device_get_peer: - * @row: a #TeleportRemoteDevice - * - * Retrieves the #Peer that @row manages, or %NULL if none - * is set. - * - * Returns: (transfer none): the internal peer of @row - */ Peer * - teleport_remote_device_get_peer (GtkWidget *widget) +teleport_remote_device_get_peer (GtkWidget *widget) { TeleportRemoteDevice *row; @@ -383,47 +225,14 @@ teleport_remote_device_set_peer (TeleportRemoteDevice *widget, g_return_if_fail (TELEPORT_IS_REMOTE_DEVICE (widget)); widget->peer = peer; - /* - we need to create a peer object instate of a struct to be able to bind it - if (!g_set_object (&widget->peer, peer)) - return; - - g_object_bind_property (peer, - "name", - widget->device_name, - "label", - G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); - */ - if (peer) { - gtk_label_set_text(GTK_LABEL (widget->device_name), peer->name); - + adw_preferences_row_set_title (ADW_PREFERENCES_ROW (widget), peer->name); g_signal_connect (widget->send_btn, "clicked", G_CALLBACK (open_file_picker), peer); - - - g_signal_connect (widget, "drag-data-received", - G_CALLBACK(drag_data_received_handl), peer); - - g_signal_connect (widget, "drag-leave", - G_CALLBACK (drag_leave_handl), peer); - - g_signal_connect (widget, "drag-motion", - G_CALLBACK (drag_motion_handl), peer); - - g_signal_connect (widget, "drag-drop", - G_CALLBACK (drag_drop_handl), peer); } } -/** - * teleport_remote_device_destroy: - * @self: a #TeleportRemoteDevice - * - * Destroy @self after hiding it. - */ void teleport_remote_device_destroy (TeleportRemoteDevice *self) { -} - +} \ No newline at end of file diff --git a/src/teleport-remote-device.h b/src/teleport-remote-device.h index c0d8d94..d4441c7 100644 --- a/src/teleport-remote-device.h +++ b/src/teleport-remote-device.h @@ -19,15 +19,14 @@ #ifndef TELEPORT_REMOTE_DEVICE_H #define TELEPORT_REMOTE_DEVICE_H -#include -#include +#include #include "teleport-peer.h" G_BEGIN_DECLS #define TELEPORT_TYPE_REMOTE_DEVICE (teleport_remote_device_get_type()) -G_DECLARE_FINAL_TYPE (TeleportRemoteDevice, teleport_remote_device, TELEPORT, REMOTE_DEVICE, GtkFrame) +G_DECLARE_FINAL_TYPE (TeleportRemoteDevice, teleport_remote_device, TELEPORT, REMOTE_DEVICE, AdwActionRow) GtkWidget * teleport_remote_device_new (Peer * ); diff --git a/src/teleport-window.c b/src/teleport-window.c index 805709c..0652481 100644 --- a/src/teleport-window.c +++ b/src/teleport-window.c @@ -1,25 +1,23 @@ /* teleport-window.c - * + * * Copyright 2017 Julian Sparber - * + * * Teleport is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include +#include #include -#define HANDY_USE_UNSTABLE_API -#include #include "teleport-app.h" #include "teleport-window.h" @@ -29,7 +27,7 @@ struct _TeleportWindow { - GtkApplicationWindow parent; + AdwApplicationWindow parent; }; typedef struct _TeleportWindowPrivate TeleportWindowPrivate; @@ -39,27 +37,51 @@ struct _TeleportWindowPrivate GtkWidget *gears; GtkWidget *this_device_settings_button; GtkWidget *remote_devices_box; - GtkWidget *this_device_name_label; + AdwActionRow *this_device_row; GtkWidget *remote_no_devices; GtkWidget *remote_no_avahi; GtkWidget *this_device_settings_entry; }; -G_DEFINE_TYPE_WITH_PRIVATE(TeleportWindow, teleport_window, GTK_TYPE_APPLICATION_WINDOW); +G_DEFINE_TYPE_WITH_PRIVATE(TeleportWindow, teleport_window, ADW_TYPE_APPLICATION_WINDOW); static void -change_download_directory_cb (GtkWidget *widget, - gpointer user_data) { - GSettings *settings; - gchar * newDownloadDir; - settings = (GSettings *)user_data; +on_download_dir_response (GtkNativeDialog *dialog, + int response, + gpointer user_data) +{ + GSettings *settings = user_data; - newDownloadDir = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); - g_print ("Change download directory\n"); - g_settings_set_string (settings, - "download-dir", - newDownloadDir); - g_free(newDownloadDir); + if (response == GTK_RESPONSE_ACCEPT) + { + g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog)); + g_autofree char *path = g_file_get_path (file); + if (path) + { + g_print ("Change download directory to %s\n", path); + g_settings_set_string (settings, "download-dir", path); + } + } + + g_object_unref (dialog); +} + +static void +on_choose_download_dir_clicked (GtkButton *btn, + gpointer user_data) +{ + GSettings *settings = user_data; + GtkFileChooserNative *dialog; + GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (btn)); + + dialog = gtk_file_chooser_native_new ("Choose Download Directory", + GTK_WINDOW (root), + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + "_Select", + "_Cancel"); + + g_signal_connect (dialog, "response", G_CALLBACK (on_download_dir_response), settings); + gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog)); } static gboolean @@ -71,7 +93,7 @@ valid_device_name (const gchar *name) { static gchar * get_new_name (GtkWidget *widget) { - return g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)))); + return g_strstrip (g_strdup (gtk_editable_get_text (GTK_EDITABLE (widget)))); } static void @@ -81,16 +103,6 @@ on_new_device_name (GtkWidget *widget, gtk_widget_set_sensitive (GTK_WIDGET (data), valid_device_name (name)); } -static void -update_download_directory (GSettings *settings, - gchar *key, - gpointer *data) { - if (g_strcmp0 (key, "download-dir") == 0) { - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (data), - g_settings_get_string(settings, key)); - } -} - static void on_click_this_device_settings_button (GtkWidget *widget, gpointer user_data) { @@ -108,7 +120,7 @@ static void on_show_popover (GtkPopover *widget, gpointer data) { TeleportWindowPrivate *priv = (TeleportWindowPrivate *) data; - gtk_entry_set_text(GTK_ENTRY (priv->this_device_settings_entry), + gtk_editable_set_text(GTK_EDITABLE (priv->this_device_settings_entry), g_settings_get_string(teleport_app_get_settings (), "device-name")); } @@ -119,31 +131,27 @@ teleport_window_init (TeleportWindow *win) TeleportWindowPrivate *priv; GtkBuilder *builder; GtkWidget *menu; - GtkFileChooserButton *downloadDir; + GtkWidget *downloadDirBtn; GSettings *settings = teleport_app_get_settings (); priv = teleport_window_get_instance_private (win); - g_type_ensure (HDY_TYPE_COLUMN); + g_type_ensure (ADW_TYPE_CLAMP); + g_type_ensure (ADW_TYPE_TOOLBAR_VIEW); + g_type_ensure (ADW_TYPE_ACTION_ROW); gtk_widget_init_template (GTK_WIDGET (win)); builder = gtk_builder_new_from_resource ("/com/frac_tion/teleport/settings.ui"); menu = GTK_WIDGET (gtk_builder_get_object (builder, "settings")); - downloadDir = GTK_FILE_CHOOSER_BUTTON (gtk_builder_get_object (builder, "settings_download_directory")); + downloadDirBtn = GTK_WIDGET (gtk_builder_get_object (builder, "settings_download_directory")); gtk_menu_button_set_popover(GTK_MENU_BUTTON (priv->gears), menu); - g_settings_bind (settings, "device-name", - priv->this_device_name_label, "label", + priv->this_device_row, "title", G_SETTINGS_BIND_GET); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (downloadDir), - g_settings_get_string(settings, - "download-dir")); - - g_signal_connect (downloadDir, "file-set", G_CALLBACK (change_download_directory_cb), settings); - g_signal_connect (settings, "changed", G_CALLBACK (update_download_directory), downloadDir); + g_signal_connect (downloadDirBtn, "clicked", G_CALLBACK (on_choose_download_dir_clicked), settings); g_object_unref (builder); @@ -185,24 +193,12 @@ update_remote_device_list(TeleportWindow *win, priv = teleport_window_get_instance_private (win); - gtk_widget_hide (priv->remote_no_devices); + gtk_widget_set_visible (priv->remote_no_devices, FALSE); remote_device = teleport_remote_device_new (device); - gtk_box_pack_end (GTK_BOX (priv->remote_devices_box), - remote_device, - TRUE, - TRUE, - 0); -} - -static void -remove_remote_peer (GtkWidget *widget, - gpointer data) -{ - if (TELEPORT_IS_REMOTE_DEVICE (widget) && teleport_remote_device_get_peer(widget) == ((Peer *) data)) { - gtk_widget_destroy (widget); - } + gtk_box_append (GTK_BOX (priv->remote_devices_box), + remote_device); } void @@ -210,12 +206,18 @@ update_remote_device_list_remove(TeleportWindow *win, Peer *device) { TeleportWindowPrivate *priv; + GtkWidget *child; priv = teleport_window_get_instance_private (win); - gtk_container_foreach (GTK_CONTAINER(priv->remote_devices_box), - remove_remote_peer, - device); + child = gtk_widget_get_first_child (priv->remote_devices_box); + while (child) { + GtkWidget *next = gtk_widget_get_next_sibling (child); + if (TELEPORT_IS_REMOTE_DEVICE (child) && teleport_remote_device_get_peer(child) == device) { + gtk_box_remove (GTK_BOX (priv->remote_devices_box), child); + } + child = next; + } } static void @@ -234,7 +236,7 @@ teleport_window_class_init (TeleportWindowClass *class) gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, gears); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_settings_button); - gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_name_label); + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, this_device_row); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_no_devices); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_devices_box); gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (class), TeleportWindow, remote_no_avahi); @@ -251,10 +253,7 @@ teleport_show_no_device_message (TeleportWindow *self, gboolean show) { TeleportWindowPrivate *priv; priv = teleport_window_get_instance_private (self); - if (show) - gtk_widget_show (priv->remote_no_devices); - else - gtk_widget_hide (priv->remote_no_devices); + gtk_widget_set_visible (priv->remote_no_devices, show); } void @@ -262,16 +261,11 @@ teleport_show_no_avahi_message (TeleportWindow *self, gboolean show) { TeleportWindowPrivate *priv; priv = teleport_window_get_instance_private (self); - if (show) - gtk_widget_show (priv->remote_no_avahi); - else - gtk_widget_hide (priv->remote_no_avahi); + gtk_widget_set_visible (priv->remote_no_avahi, show); } void teleport_window_open (TeleportWindow *win, GFile *file) { - //TeleportWindowPrivate *priv; - //priv = teleport_window_get_instance_private (win); -} +} \ No newline at end of file diff --git a/src/teleport-window.h b/src/teleport-window.h index d912c95..fc2aab9 100644 --- a/src/teleport-window.h +++ b/src/teleport-window.h @@ -19,7 +19,7 @@ #ifndef __TELEPORT_WINDOW_H #define __TELEPORT_WINDOW_H -#include +#include #include "teleport-app.h" #include "teleport-peer.h" @@ -28,7 +28,7 @@ G_DECLARE_FINAL_TYPE (TeleportWindow, teleport_window, TELEPORT, WINDOW, - GtkApplicationWindow) + AdwApplicationWindow) TeleportWindow *teleport_window_new (TeleportApp *); void teleport_window_open (TeleportWindow *, diff --git a/src/window.ui b/src/window.ui index fc84652..17d71ea 100644 --- a/src/window.ui +++ b/src/window.ui @@ -1,166 +1,84 @@ - - -