2121 */
2222
2323public 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
0 commit comments