Changes
3 changed files (+113/-72)
-
-
@@ -270,6 +270,7 @@ }fn saveState(self: *CApi, state: State) void { const file_path = self.internal.state_file_path orelse { std.log.debug("State file path is not set, skipping", .{}); return; };
-
@@ -421,6 +422,13 @@ });continue; }; defer self.internal.allocator.free(token); self.saveState(.{ .connection = .{ .server_id = server_id, .token = token, }, }); const server = self.internal.allocator.create(Server.CApi) catch { self.internal.capi_lock.lock();
-
-
-
@@ -178,7 +178,7 @@ public ConnectionState connection;public Server? server; [CCode (cname = "plac_app_set_state_path")] public void set_state_path(string path); public void set_state_path(string path, uint path_len); [CCode (cname = "plac_app_restore_state")] public void restore_state();
-
-
-
@@ -89,78 +89,118 @@ Object(application: app);this.core = core; } private string? get_and_create_state_dir() { var state_dir = GLib.Environment.get_user_state_dir(); var dir = GLib.Path.build_path(GLib.Path.DIR_SEPARATOR_S, state_dir, application.application_id); var file = GLib.File.new_for_path(dir); if (!file.query_exists()) { try { file.make_directory(); } catch (Error e) { stderr.printf("Unable to create state directory: %s\n", e.message); return null; } } return dir; } private void set_state_file() { var dir = get_and_create_state_dir(); if (dir == null) { return; } var state_path = GLib.Path.build_path(GLib.Path.DIR_SEPARATOR_S, dir, "state.json"); core.set_state_path(state_path, state_path.length); } public void start() { core.server_selector.on_change(() => { switch (core.server_selector.state) { case PlacCore.ServerSelectorState.REFRESHING: case PlacCore.ServerSelectorState.LOADING: failure_banner.revealed = false; if (error_detail_hid > 0) { failure_banner.disconnect(error_detail_hid); error_detail_hid = 0; } stack.visible_child_name = "loading"; scan_button.set_sensitive(false); break; case PlacCore.ServerSelectorState.NOT_LOADED: break; case PlacCore.ServerSelectorState.LOADED: servers_list.remove_all(); this.set_state_file(); // TODO: Make this (and possibly other callbacks) async, so access to GTK will be safe. core.on_restore_complete(() => { if (core.connection == PlacCore.ConnectionState.IDLE) { core.server_selector.on_change(() => { switch (core.server_selector.state) { case PlacCore.ServerSelectorState.REFRESHING: case PlacCore.ServerSelectorState.LOADING: failure_banner.revealed = false; if (error_detail_hid > 0) { failure_banner.disconnect(error_detail_hid); error_detail_hid = 0; } stack.visible_child_name = "loading"; scan_button.set_sensitive(false); break; case PlacCore.ServerSelectorState.NOT_LOADED: break; case PlacCore.ServerSelectorState.LOADED: servers_list.remove_all(); if (core.server_selector.entries.length == 0) { servers_list.visible = false; empty.visible = true; scan_button.add_css_class("suggested-action"); } else { servers_list.visible = true; empty.visible = false; scan_button.remove_css_class("suggested-action"); } if (core.server_selector.entries.length == 0) { servers_list.visible = false; empty.visible = true; scan_button.add_css_class("suggested-action"); } else { servers_list.visible = true; empty.visible = false; scan_button.remove_css_class("suggested-action"); } foreach (unowned PlacCore.ServerSelectorEntry entry in core.server_selector.entries) { var row = new Adw.ActionRow(); row.title = entry.name; row.subtitle = entry.version; var main_window = new MainWindow(this.application, core); row.activatable_widget = main_window; foreach (unowned PlacCore.ServerSelectorEntry entry in core.server_selector.entries) { var row = new Adw.ActionRow(); row.title = entry.name; row.subtitle = entry.version; row.activated.connect(() => { main_window.start(); core.connect(entry.id, entry.id.length, null, 0); this.close(); }); var main_window = new MainWindow(this.application, core, entry); row.activatable_widget = main_window; servers_list.append(row); } row.activated.connect(() => { main_window.start(); main_window.present(); core.connect(entry.id, entry.id.length, null, 0); this.close(); }); stack.visible_child_name = "idle"; scan_button.set_sensitive(true); servers_list.append(row); break; case PlacCore.ServerSelectorState.ERR_UNEXPECTED: show_error(ScanErrorKind.UNEXPECTED_ERROR, "Unexpected error"); break; case PlacCore.ServerSelectorState.ERR_NETWORK_UNAVAILABLE: show_error(ScanErrorKind.NETWORK_ERROR, "Network unavailable"); break; case PlacCore.ServerSelectorState.ERR_SOCKET_PERMISSION: show_error(ScanErrorKind.NETWORK_ERROR, "No permission to create UDP socket"); break; case PlacCore.ServerSelectorState.ERR_OUT_OF_MEMORY: show_error(ScanErrorKind.UNEXPECTED_ERROR, "Out of memory"); break; case PlacCore.ServerSelectorState.ERR_SOCKET: show_error(ScanErrorKind.NETWORK_ERROR, "Failed to operate on a socket"); break; case PlacCore.ServerSelectorState.ERR_THREAD_SPAWN: show_error(ScanErrorKind.UNEXPECTED_ERROR, "Unable to spawn a thread"); break; } }); stack.visible_child_name = "idle"; scan_button.set_sensitive(true); break; case PlacCore.ServerSelectorState.ERR_UNEXPECTED: show_error(ScanErrorKind.UNEXPECTED_ERROR, "Unexpected error"); break; case PlacCore.ServerSelectorState.ERR_NETWORK_UNAVAILABLE: show_error(ScanErrorKind.NETWORK_ERROR, "Network unavailable"); break; case PlacCore.ServerSelectorState.ERR_SOCKET_PERMISSION: show_error(ScanErrorKind.NETWORK_ERROR, "No permission to create UDP socket"); break; case PlacCore.ServerSelectorState.ERR_OUT_OF_MEMORY: show_error(ScanErrorKind.UNEXPECTED_ERROR, "Out of memory"); break; case PlacCore.ServerSelectorState.ERR_SOCKET: show_error(ScanErrorKind.NETWORK_ERROR, "Failed to operate on a socket"); break; case PlacCore.ServerSelectorState.ERR_THREAD_SPAWN: show_error(ScanErrorKind.UNEXPECTED_ERROR, "Unable to spawn a thread"); break; core.server_selector.load(); return; } else if (core.connection == PlacCore.ConnectionState.BUSY) { var window = new MainWindow(application, core); window.start(); this.close(); } }); core.server_selector.load(); core.restore_state(); var scan_action = new SimpleAction("scan_servers", null); scan_action.activate.connect(core.server_selector.load);
-
@@ -210,16 +250,13 @@ [GtkChild]private unowned Gtk.Label test_label; private unowned PlacCore.App core; private unowned PlacCore.ServerSelectorEntry entry; public MainWindow(Gtk.Application app, PlacCore.App core, PlacCore.ServerSelectorEntry entry) { public MainWindow(Gtk.Application app, PlacCore.App core) { Object(application: app); this.entry = entry; this.core = core; } public void start() { test_label.label = this.entry.name; core.on_connection_change(() => { switch (core.connection) { case PlacCore.ConnectionState.IDLE:
-
@@ -233,16 +270,12 @@ test_label.label = core.connection.to_string();break; } }); this.present(); } private void idle_render() { if (core.server == null) { return; } if (core.server.id != entry.id) { // TODO: Log or do something? this.close(); return; }
-