Skip to content

Commit 3032f94

Browse files
jeremypwJeremy Wootten
andauthored
Fix send files by Bluetooth (#41)
Co-authored-by: Jeremy Wootten <jeremy@Proteus-EL07R6-9b3c42bb.localdomain>
1 parent 947d795 commit 3032f94

4 files changed

Lines changed: 86 additions & 77 deletions

File tree

src/Application.vala

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@
2121
*/
2222

2323
public class BluetoothApp : Gtk.Application {
24-
public const OptionEntry[] OPTIONS_BLUETOOTH = {
25-
{ "silent", 's', 0, OptionArg.NONE, out silent, "Run the Application in background", null},
26-
{ "send", 'f', 0, OptionArg.FILENAME_ARRAY, out arg_files, "Open file to send via Bluetooth", "FILE…" },
27-
{ null }
28-
};
29-
3024
public Bluetooth.ObjectManager object_manager;
3125
public Bluetooth.Obex.Agent agent_obex;
3226
public Bluetooth.Obex.Transfer transfer;
@@ -35,82 +29,99 @@ public class BluetoothApp : Gtk.Application {
3529
public BtScan bt_scan = null;
3630
public GLib.List<BtReceiver> bt_receivers;
3731
public GLib.List<SenderDialog> bt_senders;
38-
public static bool silent = true;
39-
public static bool active_once;
40-
[CCode (array_length = false, array_null_terminated = true)]
41-
public static string[]? arg_files = null;
32+
private bool is_silent = false; // Running in background. Only access by primary instance
33+
private bool active_once = false; // Bluetooth.Obex.Agent created. Only access by primary instance
4234

4335
construct {
44-
application_id = "io.elementary.bluetooth";
36+
application_id = "io.elementary.bluetooth"; //Ensures a unique instance
4537
flags |= ApplicationFlags.HANDLES_COMMAND_LINE;
4638
Intl.setlocale (LocaleCategory.ALL, "");
47-
add_main_option_entries (OPTIONS_BLUETOOTH);
39+
add_main_option ("silent", 's', 0, OptionArg.NONE, _("Run the Application in the background"), null);
40+
add_main_option ("send", 'f', 0, OptionArg.STRING_ARRAY, _("Transfer files to a Bluetooth device"), null);
4841
}
4942

50-
private File[] create_files_for_args (ApplicationCommandLine command, string[] args) {
51-
File[] files = {};
52-
53-
foreach (unowned string arg in args) {
54-
var file = command.create_file_for_arg (arg);
55-
if (!file.query_exists ()) {
56-
stderr.printf (
57-
"Ignoring not found file: %s\n",
58-
file.get_path ()
59-
);
60-
continue;
43+
private void scan_and_send_files (Gee.ArrayList files) {
44+
Idle.add (() => {
45+
if (!object_manager.ready) {
46+
return Source.CONTINUE;
6147
}
6248

63-
files += file;
64-
}
65-
66-
return files;
67-
}
68-
69-
private void scan_and_send_files (File[] files) {
70-
if (bt_scan == null) {
71-
bt_scan = new BtScan (this, object_manager);
72-
Idle.add (() => { // Wait for async BtScan initialisation
73-
bt_scan.show_all ();
74-
return Source.REMOVE;
75-
});
76-
} else {
77-
bt_scan.present ();
78-
}
79-
80-
bt_scan.destroy.connect (() => {
81-
bt_scan = null;
82-
});
49+
if (bt_scan == null) {
50+
bt_scan = new BtScan (this, object_manager);
51+
bt_scan.destroy.connect (() => {
52+
bt_scan = null;
53+
});
8354

84-
bt_scan.send_file.connect ((device) => {
85-
if (!insert_sender (files, device)) {
86-
bt_sender = new SenderDialog (this);
87-
bt_sender.add_files (files, device);
88-
bt_senders.append (bt_sender);
89-
bt_sender.show_all ();
90-
bt_sender.destroy.connect (() => {
91-
bt_senders.foreach ((sender) => {
92-
if (sender.device == bt_sender.device) {
93-
bt_senders.remove_link (bt_senders.find (sender));
94-
}
95-
});
55+
bt_scan.send_file.connect ((device) => {
56+
if (!insert_sender (files, device)) {
57+
bt_sender = new SenderDialog (this);
58+
bt_sender.add_files (files, device);
59+
bt_senders.append (bt_sender);
60+
bt_sender.show_all ();
61+
bt_sender.destroy.connect (() => {
62+
bt_senders.foreach ((sender) => {
63+
if (sender.device == bt_sender.device) {
64+
bt_senders.remove_link (bt_senders.find (sender));
65+
}
66+
});
67+
});
68+
}
9669
});
70+
71+
bt_scan.init ();
72+
return Source.CONTINUE; // Wait for initialisation
73+
} else {
74+
bt_scan.present ();
9775
}
76+
77+
return Source.REMOVE;
9878
});
9979
}
10080

81+
// Only the primary instance runs this so we can reference `is_silent` and `active_once` here
10182
public override int command_line (ApplicationCommandLine command) {
102-
activate ();
83+
ensure_object_manager ();
84+
85+
unowned var options = command.get_options_dict ();
86+
if (!is_silent) {
87+
bool silent;
88+
options.lookup ("silent", "b", out silent);
89+
if (silent) {
90+
is_silent = true;
91+
if (active_once) { // after process hold exist.
92+
release (); // Protect from multiple holds. Has no effect if not already held.
93+
}
94+
95+
hold ();
96+
}
97+
}
10398

10499
// Handle "send" option
105-
if (arg_files != null) {
106-
File[] files = create_files_for_args (command, arg_files);
100+
if (options.contains ("send")) {
101+
var filenames = options.lookup_value ("send", VariantType.STRING_ARRAY).get_strv ();
102+
if (filenames != null) {
103+
var files = new Gee.ArrayList<File> ();
104+
foreach (unowned string arg in filenames) {
105+
var file = command.create_file_for_arg (arg);
106+
if (!file.query_exists ()) {
107+
stderr.printf (
108+
"Ignoring not found file: %s\n",
109+
file.get_path ()
110+
);
111+
continue;
112+
}
107113

108-
if (files.length > 0) {
109-
scan_and_send_files (files);
114+
files.add (file);
115+
}
116+
117+
if (files.size > 0) {
118+
scan_and_send_files (files);
119+
}
110120
}
111121
}
112122

113-
return 0;
123+
return Posix.EXIT_SUCCESS;
124+
114125
}
115126

116127
protected override void startup () {
@@ -128,15 +139,7 @@ public class BluetoothApp : Gtk.Application {
128139
});
129140
}
130141

131-
protected override void activate () {
132-
if (silent) {
133-
if (active_once) { // after process hold exist.
134-
release (); // Protect from multiple holds. Has no effect if not already held.
135-
}
136-
hold ();
137-
silent = false;
138-
}
139-
142+
private void ensure_object_manager () {
140143
if (object_manager == null) {
141144
bt_receivers = new GLib.List<BtReceiver> ();
142145
bt_senders = new GLib.List<SenderDialog> ();
@@ -206,7 +209,7 @@ public class BluetoothApp : Gtk.Application {
206209
});
207210
}
208211

209-
private bool insert_sender (File[] files, Bluetooth.Device device) {
212+
private bool insert_sender (Gee.ArrayList<File> files, Bluetooth.Device device) {
210213
bool exist = false;
211214
bt_senders.foreach ((sender) => {
212215
if (sender.device == device) {
@@ -215,6 +218,7 @@ public class BluetoothApp : Gtk.Application {
215218
exist = true;
216219
}
217220
});
221+
218222
return exist;
219223
}
220224

src/Dialog/BtScan.vala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,15 @@ public class BtScan : Granite.Dialog {
112112
destroy ();
113113
});
114114
}
115-
public override void show () {
116-
base.show ();
115+
116+
public void init () {
117117
var devices = manager.get_devices ();
118118
foreach (var device in devices) {
119119
add_device (device);
120120
}
121-
manager.start_discovery.begin ();
121+
manager.start_discovery.begin (() => {
122+
show_all ();
123+
});
122124
}
123125

124126
private void add_device (Bluetooth.Device device) {

src/Dialog/SenderDialog.vala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public class SenderDialog : Granite.Dialog {
145145
});
146146
}
147147

148-
public void add_files (File [] files, Bluetooth.Device device) {
148+
public void add_files (Gee.ArrayList<File> files, Bluetooth.Device device) {
149149
foreach (var file in files) {
150150
Gtk.TreeIter iter;
151151
liststore.append (out iter);
@@ -161,7 +161,7 @@ public class SenderDialog : Granite.Dialog {
161161
create_session.begin ();
162162
}
163163

164-
public void insert_files (File [] files) {
164+
public void insert_files (Gee.ArrayList<File> files) {
165165
foreach (var file in files) {
166166
bool exist = false;
167167
liststore.foreach ((model, path, iter) => {

src/Services/Manager.vala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class Bluetooth.ObjectManager : Object {
2121
public signal void status_discovering ();
2222

2323
public bool has_adapter { get; private set; default = false; }
24+
public bool ready { get; private set; default = false; }
2425
private bool is_powered { get; set; default = false; }
2526

2627
private Settings settings;
@@ -30,7 +31,9 @@ public class Bluetooth.ObjectManager : Object {
3031
construct {
3132
settings = new Settings ("io.elementary.desktop.bluetooth");
3233

33-
create_manager.begin ();
34+
create_manager.begin (() => {
35+
ready = true;
36+
});
3437

3538
rfkill = new RFKillManager ();
3639
rfkill.open ();

0 commit comments

Comments
 (0)