Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #include "config.h"
5 : :
6 : : #include <gio/gio.h>
7 : : #include <gtk/gtk.h>
8 : : #include <valent.h>
9 : :
10 : : #include "valent-input-remote.h"
11 : : #include "valent-media-window.h"
12 : : #include "valent-messages-window.h"
13 : : #include "valent-share-dialog.h"
14 : : #include "valent-ui-utils-private.h"
15 : : #include "valent-window.h"
16 : :
17 : : #include "valent-gnome-application.h"
18 : :
19 : :
20 : : struct _ValentGNOMEApplication
21 : : {
22 : : ValentApplicationPlugin parent_instance;
23 : :
24 : : GApplication *application;
25 : :
26 : : GtkWindow *main_window;
27 : : GtkWindow *input_remote;
28 : : GtkWindow *media_window;
29 : : GtkWindow *messages_window;
30 : : GPtrArray *windows;
31 : : };
32 : :
33 [ + + + - ]: 68 : G_DEFINE_FINAL_TYPE (ValentGNOMEApplication, valent_gnome_application, VALENT_TYPE_APPLICATION_PLUGIN)
34 : :
35 : :
36 : : /*
37 : : * GActions
38 : : */
39 : : static void
40 : 0 : main_window_action (GSimpleAction *action,
41 : : GVariant *parameter,
42 : : gpointer user_data)
43 : : {
44 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (user_data);
45 : :
46 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
47 : :
48 [ # # ]: 0 : if (self->main_window == NULL)
49 : : {
50 : 0 : ValentDeviceManager *devices = valent_device_manager_get_default ();
51 : :
52 : 0 : self->main_window = g_object_new (VALENT_TYPE_WINDOW,
53 : : "default-width", 600,
54 : : "default-height", 480,
55 : : "device-manager", devices,
56 : : NULL);
57 : 0 : g_object_add_weak_pointer (G_OBJECT (self->main_window),
58 : 0 : (gpointer)&self->main_window);
59 : :
60 [ # # ]: 0 : if (self->application != NULL)
61 : : {
62 : 0 : gtk_widget_insert_action_group (GTK_WIDGET (self->main_window),
63 : : "app",
64 : : G_ACTION_GROUP (self->application));
65 : : }
66 : : }
67 : :
68 : 0 : gtk_window_present (self->main_window);
69 : 0 : gtk_widget_activate_action_variant (GTK_WIDGET (self->main_window),
70 : : "win.page",
71 : : parameter);
72 : 0 : }
73 : :
74 : : static void
75 : 0 : input_remote_action (GSimpleAction *action,
76 : : GVariant *parameter,
77 : : gpointer user_data)
78 : : {
79 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (user_data);
80 : :
81 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
82 : :
83 [ # # ]: 0 : if (self->input_remote == NULL)
84 : : {
85 : 0 : self->input_remote = g_object_new (VALENT_TYPE_INPUT_REMOTE,
86 : : "adapters", valent_input_get_default (),
87 : : NULL);
88 : 0 : g_object_add_weak_pointer (G_OBJECT (self->input_remote),
89 : 0 : (gpointer)&self->input_remote);
90 : : }
91 : :
92 : 0 : gtk_window_present (self->input_remote);
93 : 0 : }
94 : :
95 : : static void
96 : 0 : media_window_action (GSimpleAction *action,
97 : : GVariant *parameter,
98 : : gpointer user_data)
99 : : {
100 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (user_data);
101 : :
102 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
103 : :
104 [ # # ]: 0 : if (self->media_window == NULL)
105 : : {
106 : 0 : self->media_window = g_object_new (VALENT_TYPE_MEDIA_WINDOW,
107 : : "mixers", valent_mixer_get_default (),
108 : : "players", valent_media_get_default (),
109 : : NULL);
110 : 0 : g_object_add_weak_pointer (G_OBJECT (self->media_window),
111 : 0 : (gpointer)&self->media_window);
112 : : }
113 : :
114 : 0 : gtk_window_present (self->media_window);
115 : 0 : }
116 : :
117 : : static void
118 : 0 : messages_window_action (GSimpleAction *action,
119 : : GVariant *parameter,
120 : : gpointer user_data)
121 : : {
122 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (user_data);
123 : :
124 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
125 : :
126 [ # # ]: 0 : if (self->messages_window == NULL)
127 : : {
128 : 0 : self->messages_window = g_object_new (VALENT_TYPE_MESSAGES_WINDOW, NULL);
129 : 0 : g_object_add_weak_pointer (G_OBJECT (self->messages_window),
130 : 0 : (gpointer)&self->messages_window);
131 : : }
132 : :
133 : 0 : gtk_window_present (self->messages_window);
134 : 0 : }
135 : :
136 : : static void
137 : 0 : on_destroy (GtkWindow *window,
138 : : ValentGNOMEApplication *self)
139 : : {
140 : 0 : unsigned int index;
141 : :
142 [ # # # # : 0 : g_assert (GTK_IS_WINDOW (window));
# # # # ]
143 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
144 : :
145 : : /* The signal was emitted because we're disposing or being disabled */
146 [ # # ]: 0 : if (self->windows == NULL)
147 : 0 : return;
148 : :
149 [ # # ]: 0 : if (g_ptr_array_find (self->windows, window, &index))
150 : 0 : g_ptr_array_steal_index (self->windows, index);
151 : : }
152 : :
153 : : static void
154 : 0 : valent_share_target_present (ValentGNOMEApplication *self,
155 : : GListModel *files)
156 : : {
157 : 0 : GtkWindow *window = NULL;
158 : :
159 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
160 [ # # # # ]: 0 : g_assert (files == NULL || G_IS_LIST_MODEL (files));
161 : :
162 : 0 : window = g_object_new (VALENT_TYPE_SHARE_DIALOG,
163 : : "files", files,
164 : : NULL);
165 : 0 : g_signal_connect_object (G_OBJECT (window),
166 : : "destroy",
167 : : G_CALLBACK (on_destroy),
168 : : self,
169 : : G_CONNECT_DEFAULT);
170 : 0 : g_ptr_array_add (self->windows, window);
171 : :
172 : 0 : gtk_window_present (window);
173 : 0 : }
174 : :
175 : : static inline void
176 : 0 : share_dialog_action (GSimpleAction *action,
177 : : GVariant *parameters,
178 : : gpointer user_data)
179 : : {
180 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (user_data);
181 : :
182 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (self));
183 : :
184 : 0 : valent_share_target_present (self, NULL);
185 : 0 : }
186 : :
187 : : static const GActionEntry app_actions[] = {
188 : : { "input-remote", input_remote_action, NULL, NULL, NULL },
189 : : { "media-window", media_window_action, NULL, NULL, NULL },
190 : : { "messages-window", messages_window_action, NULL, NULL, NULL },
191 : : { "share-dialog", share_dialog_action, NULL, NULL, NULL },
192 : : { "window", main_window_action, "s", NULL, NULL },
193 : : };
194 : :
195 : :
196 : : /*
197 : : * ValentApplicationPlugin
198 : : */
199 : : static gboolean
200 : 0 : valent_gnome_application_activate (ValentApplicationPlugin *plugin)
201 : : {
202 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (plugin);
203 : :
204 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (plugin));
205 : :
206 [ # # ]: 0 : if (self->application != NULL)
207 : : {
208 : 0 : g_action_group_activate_action (G_ACTION_GROUP (self->application),
209 : : "window",
210 : : g_variant_new_string ("main"));
211 : : }
212 : :
213 : 0 : return TRUE;
214 : : }
215 : :
216 : : static gboolean
217 : 0 : valent_gnome_application_open (ValentApplicationPlugin *plugin,
218 : : GFile **files,
219 : : int n_files,
220 : : const char *hint)
221 : : {
222 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (plugin);
223 : 0 : g_autoptr (GListStore) files_list = NULL;
224 : :
225 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (plugin));
226 [ # # ]: 0 : g_assert (files != NULL);
227 [ # # ]: 0 : g_assert (n_files > 0);
228 [ # # ]: 0 : g_assert (hint != NULL);
229 : :
230 : 0 : files_list = g_list_store_new (G_TYPE_FILE);
231 : 0 : g_list_store_splice (files_list, 0, 0, (gpointer *)files, n_files);
232 : 0 : valent_share_target_present (self, G_LIST_MODEL (files_list));
233 : :
234 [ # # ]: 0 : return TRUE;
235 : : }
236 : :
237 : : static void
238 : 0 : valent_gnome_application_shutdown (ValentApplicationPlugin *plugin)
239 : : {
240 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (plugin);
241 : :
242 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (plugin));
243 : :
244 [ # # ]: 0 : if (self->application != NULL)
245 : : {
246 [ # # ]: 0 : for (size_t i = 0; i < G_N_ELEMENTS (app_actions); i++)
247 : : {
248 : 0 : g_action_map_remove_action (G_ACTION_MAP (self->application),
249 : 0 : app_actions[i].name);
250 : : }
251 : : }
252 : :
253 [ # # ]: 0 : g_clear_pointer (&self->media_window, gtk_window_destroy);
254 [ # # ]: 0 : g_clear_pointer (&self->main_window, gtk_window_destroy);
255 : 0 : }
256 : :
257 : : static void
258 : 0 : valent_gnome_application_startup (ValentApplicationPlugin *plugin)
259 : : {
260 : 0 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (plugin);
261 : :
262 [ # # ]: 0 : g_assert (VALENT_IS_GNOME_APPLICATION (plugin));
263 : :
264 [ # # ]: 0 : if (self->application != NULL)
265 : : {
266 : 0 : g_action_map_add_action_entries (G_ACTION_MAP (self->application),
267 : : app_actions,
268 : : G_N_ELEMENTS (app_actions),
269 : : plugin);
270 : : }
271 : 0 : }
272 : :
273 : : /*
274 : : * ValentObject
275 : : */
276 : : static void
277 : 1 : valent_gnome_application_destroy (ValentObject *object)
278 : : {
279 : 1 : ValentGNOMEApplication *self = VALENT_GNOME_APPLICATION (object);
280 : :
281 [ + - ]: 1 : if (self->application != NULL)
282 : : {
283 [ + + ]: 6 : for (size_t i = 0; i < G_N_ELEMENTS (app_actions); i++)
284 : : {
285 : 5 : g_action_map_remove_action (G_ACTION_MAP (self->application),
286 : 5 : app_actions[i].name);
287 : : }
288 : : }
289 : :
290 [ + - ]: 1 : g_clear_pointer (&self->windows, g_ptr_array_unref);
291 : :
292 : 1 : VALENT_OBJECT_CLASS (valent_gnome_application_parent_class)->destroy (object);
293 : 1 : }
294 : :
295 : : /*
296 : : * GObject
297 : : */
298 : : static void
299 : 17 : valent_gnome_application_class_init (ValentGNOMEApplicationClass *klass)
300 : : {
301 : 17 : ValentObjectClass *vobject_class = VALENT_OBJECT_CLASS (klass);
302 : 17 : ValentApplicationPluginClass *plugin_class = VALENT_APPLICATION_PLUGIN_CLASS (klass);
303 : :
304 : 17 : vobject_class->destroy = valent_gnome_application_destroy;
305 : :
306 : 17 : plugin_class->activate = valent_gnome_application_activate;
307 : 17 : plugin_class->open = valent_gnome_application_open;
308 : 17 : plugin_class->shutdown = valent_gnome_application_shutdown;
309 : 17 : plugin_class->startup = valent_gnome_application_startup;
310 : :
311 : 17 : valent_ui_init ();
312 : : }
313 : :
314 : : static void
315 : 1 : valent_gnome_application_init (ValentGNOMEApplication *self)
316 : : {
317 : 1 : self->application = g_application_get_default ();
318 : 1 : self->windows = g_ptr_array_new_with_free_func ((GDestroyNotify)gtk_window_destroy);
319 : 1 : }
320 : :
|