54
by Ted Gould
Adding in license headers, GPL v3 |
1 |
/*
|
2 |
An indicator to show information that is in messaging applications
|
|
3 |
that the user is using.
|
|
4 |
||
272.3.1
by Charles Kerr
add lars as co-author of app-section |
5 |
Copyright 2012 Canonical Ltd.
|
54
by Ted Gould
Adding in license headers, GPL v3 |
6 |
|
7 |
Authors:
|
|
272.3.1
by Charles Kerr
add lars as co-author of app-section |
8 |
Lars Uebernickel <lars.uebernickel@canonical.com>
|
54
by Ted Gould
Adding in license headers, GPL v3 |
9 |
Ted Gould <ted@canonical.com>
|
10 |
||
11 |
This program is free software: you can redistribute it and/or modify it
|
|
12 |
under the terms of the GNU General Public License version 3, as published
|
|
13 |
by the Free Software Foundation.
|
|
14 |
||
15 |
This program is distributed in the hope that it will be useful, but
|
|
16 |
WITHOUT ANY WARRANTY; without even the implied warranties of
|
|
17 |
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
|
18 |
PURPOSE. See the GNU General Public License for more details.
|
|
19 |
||
20 |
You should have received a copy of the GNU General Public License along
|
|
21 |
with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
22 |
*/
|
|
23 |
||
49
by Ted Gould
Adding in an application menu item to start building those |
24 |
#ifdef HAVE_CONFIG_H
|
25 |
#include "config.h" |
|
26 |
#endif
|
|
27 |
||
338.1.2
by Marco Trevisan (Treviño)
AppSection: use the GAppLaunchContext with event timestamp when launching an app |
28 |
#include <gdk/gdk.h> |
49
by Ted Gould
Adding in an application menu item to start building those |
29 |
#include <glib/gi18n.h> |
61
by Ted Gould
Adding in desktop file support, which required configure changes to get the right headers. |
30 |
#include <gio/gdesktopappinfo.h> |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
31 |
#include <gio/gio.h> |
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
32 |
#include <libindicator/indicator-desktop-shortcuts.h> |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
33 |
#include "app-section.h" |
123.4.24
by Ted Gould
Defining the max number of indicators and telling the server about it. |
34 |
#include "dbus-data.h" |
272.2.63
by Lars Uebernickel
messages-service: move gmenu utility functions into gmenuutils.[ch] |
35 |
#include "gmenuutils.h" |
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
36 |
#include "gactionmuxer.h" |
49
by Ted Gould
Adding in an application menu item to start building those |
37 |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
38 |
struct _AppSectionPrivate |
49
by Ted Gould
Adding in an application menu item to start building those |
39 |
{
|
272.2.7
by Lars Uebernickel
app-menu-item: remove another unneeded priv variable |
40 |
GDesktopAppInfo * appinfo; |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
41 |
GFileMonitor *desktop_file_monitor; |
162.2.3
by Ted Gould
Fleshing out menu_cb, lots of avenues for expantion in other directions now. |
42 |
|
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
43 |
IndicatorDesktopShortcuts * ids; |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
44 |
|
45 |
GMenu *menu; |
|
272.2.88
by Lars Uebernickel
app-section: rename remote_menu to source_menu |
46 |
GMenuModel *source_menu; |
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
47 |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
48 |
GSimpleActionGroup *static_shortcuts; |
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
49 |
GActionGroup *source_actions; |
50 |
GActionMuxer *muxer; |
|
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
51 |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
52 |
gboolean draws_attention; |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
53 |
gboolean uses_chat_status; |
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
54 |
gchar *chat_status; |
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
55 |
|
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
56 |
guint name_watch_id; |
49
by Ted Gould
Adding in an application menu item to start building those |
57 |
};
|
58 |
||
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
59 |
enum { |
60 |
PROP_0, |
|
61 |
PROP_APPINFO, |
|
272.2.29
by Lars Uebernickel
Reexport application actions |
62 |
PROP_ACTIONS, |
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
63 |
PROP_DRAWS_ATTENTION, |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
64 |
PROP_USES_CHAT_STATUS, |
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
65 |
PROP_CHAT_STATUS, |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
66 |
NUM_PROPERTIES
|
67 |
};
|
|
68 |
||
69 |
static GParamSpec *properties[NUM_PROPERTIES]; |
|
308.1.3
by Lars Uebernickel
app-section.c: make destroy_signal static |
70 |
static guint destroy_signal; |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
71 |
|
49
by Ted Gould
Adding in an application menu item to start building those |
72 |
/* Prototypes */
|
272.2.23
by Lars Uebernickel
app-section: fix indentation |
73 |
static void app_section_class_init (AppSectionClass *klass); |
74 |
static void app_section_init (AppSection *self); |
|
75 |
static void app_section_get_property (GObject *object, |
|
76 |
guint property_id, |
|
77 |
GValue *value, |
|
78 |
GParamSpec *pspec); |
|
79 |
static void app_section_set_property (GObject *object, |
|
80 |
guint property_id, |
|
81 |
const GValue *value, |
|
82 |
GParamSpec *pspec); |
|
83 |
static void app_section_dispose (GObject *object); |
|
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
84 |
static void app_section_finalize (GObject *object); |
272.2.23
by Lars Uebernickel
app-section: fix indentation |
85 |
static void activate_cb (GSimpleAction *action, |
86 |
GVariant *param, |
|
87 |
gpointer userdata); |
|
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
88 |
static void launch_action_change_state (GSimpleAction *action, |
89 |
GVariant *value, |
|
90 |
gpointer user_data); |
|
272.2.23
by Lars Uebernickel
app-section: fix indentation |
91 |
static void app_section_set_app_info (AppSection *self, |
92 |
GDesktopAppInfo *appinfo); |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
93 |
static gboolean any_action_draws_attention (GActionGroup *group, |
94 |
const gchar *ignored_action); |
|
95 |
static void action_added (GActionGroup *group, |
|
96 |
const gchar *action_name, |
|
97 |
gpointer user_data); |
|
98 |
static void action_state_changed (GActionGroup *group, |
|
99 |
const gchar *action_name, |
|
100 |
GVariant *value, |
|
101 |
gpointer user_data); |
|
102 |
static void action_removed (GActionGroup *group, |
|
103 |
const gchar *action_name, |
|
104 |
gpointer user_data); |
|
272.2.67
by Lars Uebernickel
Make "Clear" work again |
105 |
static gboolean action_draws_attention (GVariant *state); |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
106 |
static void desktop_file_changed_cb (GFileMonitor *monitor, |
107 |
GFile *file, |
|
108 |
GFile *other_file, |
|
109 |
GFileMonitorEvent event, |
|
110 |
gpointer user_data); |
|
49
by Ted Gould
Adding in an application menu item to start building those |
111 |
|
123.4.40
by Ted Gould
Setting up the listener signal to make it so that we know when the count changes. Using the property call back and just calling that function. |
112 |
/* GObject Boilerplate */
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
113 |
G_DEFINE_TYPE (AppSection, app_section, G_TYPE_OBJECT); |
49
by Ted Gould
Adding in an application menu item to start building those |
114 |
|
115 |
static void |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
116 |
app_section_class_init (AppSectionClass *klass) |
49
by Ted Gould
Adding in an application menu item to start building those |
117 |
{
|
118 |
GObjectClass *object_class = G_OBJECT_CLASS (klass); |
|
119 |
||
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
120 |
g_type_class_add_private (klass, sizeof (AppSectionPrivate)); |
49
by Ted Gould
Adding in an application menu item to start building those |
121 |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
122 |
object_class->get_property = app_section_get_property; |
123 |
object_class->set_property = app_section_set_property; |
|
124 |
object_class->dispose = app_section_dispose; |
|
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
125 |
object_class->finalize = app_section_finalize; |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
126 |
|
127 |
properties[PROP_APPINFO] = g_param_spec_object ("app-info", |
|
128 |
"AppInfo", |
|
129 |
"The GAppInfo for the app that this menu represents", |
|
130 |
G_TYPE_APP_INFO, |
|
131 |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); |
|
132 |
||
272.2.29
by Lars Uebernickel
Reexport application actions |
133 |
properties[PROP_ACTIONS] = g_param_spec_object ("actions", |
134 |
"Actions", |
|
135 |
"The actions exported by this application", |
|
136 |
G_TYPE_ACTION_GROUP, |
|
137 |
G_PARAM_READABLE); |
|
138 |
||
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
139 |
properties[PROP_DRAWS_ATTENTION] = g_param_spec_boolean ("draws-attention", |
140 |
"Draws attention", |
|
141 |
"Whether the section currently draws attention", |
|
142 |
FALSE, |
|
143 |
G_PARAM_READABLE); |
|
144 |
||
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
145 |
properties[PROP_USES_CHAT_STATUS] = g_param_spec_boolean ("uses-chat-status", |
146 |
"Uses chat status", |
|
147 |
"Whether the section uses the global chat status", |
|
148 |
FALSE, |
|
149 |
G_PARAM_READABLE); |
|
150 |
||
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
151 |
properties[PROP_CHAT_STATUS] = g_param_spec_string ("chat-status", |
152 |
"Chat status", |
|
153 |
"Current chat status of the application", |
|
154 |
NULL, |
|
155 |
G_PARAM_READWRITE | |
|
156 |
G_PARAM_STATIC_STRINGS); |
|
157 |
||
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
158 |
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
159 |
|
160 |
destroy_signal = g_signal_new ("destroy", |
|
161 |
APP_SECTION_TYPE, |
|
162 |
G_SIGNAL_RUN_FIRST, |
|
163 |
0, |
|
164 |
NULL, NULL, |
|
165 |
g_cclosure_marshal_VOID__VOID, |
|
166 |
G_TYPE_NONE, 0); |
|
49
by Ted Gould
Adding in an application menu item to start building those |
167 |
}
|
168 |
||
169 |
static void |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
170 |
app_section_init (AppSection *self) |
49
by Ted Gould
Adding in an application menu item to start building those |
171 |
{
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
172 |
AppSectionPrivate *priv; |
173 |
||
174 |
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, |
|
175 |
APP_SECTION_TYPE, |
|
176 |
AppSectionPrivate); |
|
177 |
priv = self->priv; |
|
49
by Ted Gould
Adding in an application menu item to start building those |
178 |
|
61
by Ted Gould
Adding in desktop file support, which required configure changes to get the right headers. |
179 |
priv->appinfo = NULL; |
49
by Ted Gould
Adding in an application menu item to start building those |
180 |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
181 |
priv->menu = g_menu_new (); |
182 |
priv->static_shortcuts = g_simple_action_group_new (); |
|
183 |
||
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
184 |
priv->muxer = g_action_muxer_new (); |
185 |
g_action_muxer_insert (priv->muxer, NULL, G_ACTION_GROUP (priv->static_shortcuts)); |
|
186 |
||
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
187 |
priv->draws_attention = FALSE; |
188 |
||
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
189 |
return; |
190 |
}
|
|
191 |
||
49
by Ted Gould
Adding in an application menu item to start building those |
192 |
static void |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
193 |
app_section_get_property (GObject *object, |
272.2.23
by Lars Uebernickel
app-section: fix indentation |
194 |
guint property_id, |
195 |
GValue *value, |
|
196 |
GParamSpec *pspec) |
|
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
197 |
{
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
198 |
AppSection *self = APP_SECTION (object); |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
199 |
|
200 |
switch (property_id) |
|
201 |
{
|
|
202 |
case PROP_APPINFO: |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
203 |
g_value_set_object (value, app_section_get_app_info (self)); |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
204 |
break; |
205 |
||
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
206 |
case PROP_DRAWS_ATTENTION: |
207 |
g_value_set_boolean (value, app_section_get_draws_attention (self)); |
|
208 |
break; |
|
209 |
||
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
210 |
case PROP_USES_CHAT_STATUS: |
211 |
g_value_set_boolean (value, app_section_get_uses_chat_status (self)); |
|
212 |
break; |
|
213 |
||
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
214 |
case PROP_CHAT_STATUS: |
215 |
g_value_set_string (value, app_section_get_status (self)); |
|
216 |
break; |
|
217 |
||
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
218 |
default: |
219 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
|
220 |
}
|
|
221 |
}
|
|
222 |
||
223 |
static void |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
224 |
app_section_set_property (GObject *object, |
272.2.23
by Lars Uebernickel
app-section: fix indentation |
225 |
guint property_id, |
226 |
const GValue *value, |
|
227 |
GParamSpec *pspec) |
|
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
228 |
{
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
229 |
AppSection *self = APP_SECTION (object); |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
230 |
|
231 |
switch (property_id) |
|
232 |
{
|
|
233 |
case PROP_APPINFO: |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
234 |
app_section_set_app_info (self, g_value_get_object (value)); |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
235 |
break; |
236 |
||
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
237 |
case PROP_CHAT_STATUS: |
238 |
app_section_set_status (self, g_value_get_string (value)); |
|
239 |
break; |
|
240 |
||
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
241 |
default: |
242 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); |
|
243 |
}
|
|
244 |
}
|
|
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
245 |
|
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
246 |
static void |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
247 |
app_section_dispose (GObject *object) |
49
by Ted Gould
Adding in an application menu item to start building those |
248 |
{
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
249 |
AppSection * self = APP_SECTION(object); |
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
250 |
AppSectionPrivate * priv = self->priv; |
78
by Ted Gould
Disconnecting our signals properly, avoids a crash |
251 |
|
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
252 |
if (priv->desktop_file_monitor) { |
253 |
g_signal_handlers_disconnect_by_func (priv->desktop_file_monitor, desktop_file_changed_cb, self); |
|
254 |
g_clear_object (&priv->desktop_file_monitor); |
|
255 |
}
|
|
256 |
||
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
257 |
g_clear_object (&priv->menu); |
258 |
g_clear_object (&priv->static_shortcuts); |
|
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
259 |
|
272.2.25
by Lars Uebernickel
Listen to menus exported by applications |
260 |
if (priv->name_watch_id) { |
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
261 |
g_bus_unwatch_name (priv->name_watch_id); |
262 |
priv->name_watch_id = 0; |
|
263 |
}
|
|
264 |
||
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
265 |
if (priv->source_actions) { |
266 |
g_action_muxer_remove (priv->muxer, "source"); |
|
267 |
g_object_disconnect (priv->source_actions, |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
268 |
"any_signal::action-added", action_added, self, |
269 |
"any_signal::action-state-changed", action_state_changed, self, |
|
270 |
"any_signal::action-removed", action_removed, self, |
|
271 |
NULL); |
|
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
272 |
g_clear_object (&priv->source_actions); |
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
273 |
}
|
274 |
||
272.3.9
by Charles Kerr
in app-section.c's dispose(), clear the muxer object |
275 |
g_clear_object (&priv->muxer); |
276 |
||
272.2.88
by Lars Uebernickel
app-section: rename remote_menu to source_menu |
277 |
g_clear_object (&priv->source_menu); |
272.3.2
by Charles Kerr
in app-section.c's dispose(), use g_clear_object() for priv.ids and priv.keyfile |
278 |
g_clear_object (&priv->ids); |
279 |
g_clear_object (&priv->appinfo); |
|
210.1.3
by Ted Gould
Create the keyfile for the application icon as well |
280 |
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
281 |
G_OBJECT_CLASS (app_section_parent_class)->dispose (object); |
107.2.4
by Ted Gould
Moving signal disconnecting and unref to the dispose function instead of finalize. Fix by Cody Russell on bug 362124. |
282 |
}
|
283 |
||
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
284 |
static void |
285 |
app_section_finalize (GObject *object) |
|
286 |
{
|
|
287 |
AppSection * self = APP_SECTION(object); |
|
288 |
||
289 |
g_free (self->priv->chat_status); |
|
290 |
||
291 |
G_OBJECT_CLASS (app_section_parent_class)->dispose (object); |
|
292 |
}
|
|
293 |
||
340.1.2
by Marco Trevisan (Treviño)
AppSection: use LaunchContext to exec shortcut nicks |
294 |
static GAppLaunchContext * |
295 |
get_launch_context (guint32 timestamp) |
|
296 |
{
|
|
297 |
GdkDisplay *display = gdk_display_get_default(); |
|
298 |
GdkAppLaunchContext *launch_context = gdk_display_get_app_launch_context (display); |
|
299 |
||
300 |
gdk_app_launch_context_set_timestamp (launch_context, timestamp); |
|
301 |
||
302 |
return G_APP_LAUNCH_CONTEXT (launch_context); |
|
303 |
}
|
|
304 |
||
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
305 |
/* Respond to one of the shortcuts getting clicked on. */
|
306 |
static void |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
307 |
nick_activate_cb (GSimpleAction *action, |
308 |
GVariant *param, |
|
309 |
gpointer userdata) |
|
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
310 |
{
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
311 |
const gchar * nick = g_action_get_name (G_ACTION (action)); |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
312 |
AppSection * mi = APP_SECTION (userdata); |
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
313 |
AppSectionPrivate * priv = mi->priv; |
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
314 |
|
315 |
g_return_if_fail(priv->ids != NULL); |
|
316 |
||
340.1.2
by Marco Trevisan (Treviño)
AppSection: use LaunchContext to exec shortcut nicks |
317 |
GAppLaunchContext *context = get_launch_context (g_variant_get_uint32 (param)); |
318 |
||
319 |
if (!indicator_desktop_shortcuts_nick_exec_with_context(priv->ids, nick, context)) { |
|
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
320 |
g_warning("Unable to execute nick '%s' for desktop file '%s'", |
321 |
nick, g_desktop_app_info_get_filename (priv->appinfo)); |
|
322 |
}
|
|
340.1.2
by Marco Trevisan (Treviño)
AppSection: use LaunchContext to exec shortcut nicks |
323 |
|
324 |
g_object_unref (context); |
|
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
325 |
}
|
326 |
||
272.2.8
by Lars Uebernickel
Allow creating an app menu item without associated indicate server |
327 |
static void |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
328 |
keyfile_loaded (GObject *source_object, |
329 |
GAsyncResult *result, |
|
272.3.3
by Charles Kerr
add sanity checks to args passed in the public API |
330 |
gpointer user_data) |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
331 |
{
|
332 |
AppSection *self = user_data; |
|
333 |
gchar *contents; |
|
334 |
gsize length; |
|
335 |
GKeyFile *keyfile; |
|
336 |
GError *error = NULL; |
|
337 |
||
338 |
if (!g_file_load_contents_finish (G_FILE (source_object), result, |
|
339 |
&contents, &length, NULL, &error)) { |
|
340 |
g_warning ("could not read key file: %s", error->message); |
|
341 |
g_error_free (error); |
|
342 |
return; |
|
343 |
}
|
|
344 |
||
345 |
keyfile = g_key_file_new (); |
|
346 |
if (!g_key_file_load_from_data (keyfile, contents, length, 0, &error)) { |
|
347 |
g_warning ("could not read key file: %s", error->message); |
|
348 |
g_error_free (error); |
|
349 |
goto out; |
|
350 |
}
|
|
351 |
||
352 |
self->priv->uses_chat_status = g_key_file_get_boolean (keyfile, |
|
353 |
G_KEY_FILE_DESKTOP_GROUP, |
|
272.2.78
by Lars Uebernickel
X-MessagingMenu-UsesChatStatus --> X-MessagingMenu-UsesChatSection |
354 |
"X-MessagingMenu-UsesChatSection", |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
355 |
&error); |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
356 |
|
357 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); |
|
358 |
||
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
359 |
if (error) { |
360 |
if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { |
|
361 |
g_warning ("could not read X-MessagingMenu-UsesChatSection: %s", |
|
362 |
error->message); |
|
363 |
}
|
|
364 |
g_error_free (error); |
|
365 |
goto out; |
|
366 |
}
|
|
367 |
||
368 |
out: |
|
369 |
g_key_file_free (keyfile); |
|
370 |
g_free (contents); |
|
371 |
}
|
|
372 |
||
373 |
static void |
|
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
374 |
g_menu_clear (GMenu *menu) |
375 |
{
|
|
376 |
gint n_items = g_menu_model_get_n_items (G_MENU_MODEL (menu)); |
|
377 |
||
378 |
while (n_items--) |
|
379 |
g_menu_remove (menu, 0); |
|
380 |
}
|
|
381 |
||
382 |
static void |
|
383 |
g_simple_action_group_clear (GSimpleActionGroup *group) |
|
384 |
{
|
|
385 |
gchar **actions; |
|
386 |
gchar **it; |
|
387 |
||
388 |
actions = g_action_group_list_actions (G_ACTION_GROUP (group)); |
|
389 |
for (it = actions; *it; it++) |
|
390 |
g_simple_action_group_remove (group, *it); |
|
391 |
||
392 |
g_strfreev (actions); |
|
393 |
}
|
|
394 |
||
395 |
static void |
|
396 |
app_section_update_menu (AppSection *self) |
|
272.2.8
by Lars Uebernickel
Allow creating an app menu item without associated indicate server |
397 |
{
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
398 |
AppSectionPrivate *priv = self->priv; |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
399 |
GSimpleAction *launch; |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
400 |
GFile *keyfile; |
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
401 |
GMenuItem *item; |
272.2.95
by Lars Uebernickel
Show icons in application and source menu items |
402 |
gchar *iconstr; |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
403 |
gboolean is_running; |
404 |
||
405 |
g_menu_clear (priv->menu); |
|
406 |
g_simple_action_group_clear (priv->static_shortcuts); |
|
407 |
||
408 |
is_running = priv->name_watch_id > 0; |
|
338.1.2
by Marco Trevisan (Treviño)
AppSection: use the GAppLaunchContext with event timestamp when launching an app |
409 |
launch = g_simple_action_new_stateful ("launch", G_VARIANT_TYPE_UINT32, g_variant_new_boolean (is_running)); |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
410 |
g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); |
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
411 |
g_signal_connect (launch, "change-state", G_CALLBACK (launch_action_change_state), self); |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
412 |
g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); |
413 |
||
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
414 |
item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); |
415 |
g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImAppMenuItem"); |
|
272.2.95
by Lars Uebernickel
Show icons in application and source menu items |
416 |
iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); |
417 |
g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); |
|
418 |
g_free (iconstr); |
|
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
419 |
|
420 |
g_menu_append_item (priv->menu, item); |
|
421 |
g_object_unref (item); |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
422 |
|
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
423 |
/* Start to build static shortcuts */
|
424 |
priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); |
|
425 |
const gchar ** nicks = indicator_desktop_shortcuts_get_nicks(priv->ids); |
|
426 |
gint i; |
|
427 |
for (i = 0; nicks[i] != NULL; i++) { |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
428 |
gchar *name; |
429 |
GSimpleAction *action; |
|
293.1.4
by Lars Uebernickel
IdoMenuItem: don't try to set state on stateless actions |
430 |
GMenuItem *item; |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
431 |
|
432 |
name = indicator_desktop_shortcuts_nick_get_name(priv->ids, nicks[i]); |
|
433 |
||
340.1.2
by Marco Trevisan (Treviño)
AppSection: use LaunchContext to exec shortcut nicks |
434 |
action = g_simple_action_new (nicks[i], G_VARIANT_TYPE_UINT32); |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
435 |
g_signal_connect(action, "activate", G_CALLBACK (nick_activate_cb), self); |
436 |
g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (action)); |
|
272.3.10
by Charles Kerr
in app-section's app_section_set_app_info(), don't leak the nicks' actions |
437 |
g_object_unref (action); |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
438 |
|
293.1.4
by Lars Uebernickel
IdoMenuItem: don't try to set state on stateless actions |
439 |
item = g_menu_item_new (name, nicks[i]); |
440 |
g_menu_item_set_attribute (item, "x-canonical-type", "s", "IdoMenuItem"); |
|
441 |
g_menu_item_set_attribute (item, "x-canonical-icon", "s", ""); /* empty to get indentation */ |
|
442 |
g_menu_append_item (priv->menu, item); |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
443 |
|
293.1.4
by Lars Uebernickel
IdoMenuItem: don't try to set state on stateless actions |
444 |
g_object_unref (item); |
272.2.9
by Lars Uebernickel
Merge launcher- and appmenuitems |
445 |
g_free(name); |
446 |
}
|
|
447 |
||
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
448 |
keyfile = g_file_new_for_path (g_desktop_app_info_get_filename (priv->appinfo)); |
449 |
g_file_load_contents_async (keyfile, NULL, keyfile_loaded, self); |
|
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
450 |
|
451 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); |
|
452 |
||
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
453 |
g_object_unref (keyfile); |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
454 |
g_object_unref (launch); |
455 |
}
|
|
456 |
||
457 |
static void |
|
458 |
desktop_file_changed_cb (GFileMonitor *monitor, |
|
459 |
GFile *file, |
|
460 |
GFile *other_file, |
|
461 |
GFileMonitorEvent event, |
|
462 |
gpointer user_data) |
|
463 |
{
|
|
464 |
AppSection *self = user_data; |
|
465 |
||
466 |
if (event == G_FILE_MONITOR_EVENT_CHANGED) { |
|
467 |
app_section_update_menu (self); |
|
468 |
}
|
|
469 |
else if (event == G_FILE_MONITOR_EVENT_DELETED || |
|
470 |
event == G_FILE_MONITOR_EVENT_UNMOUNTED) { |
|
471 |
g_signal_emit (self, destroy_signal, 0); |
|
472 |
}
|
|
473 |
}
|
|
474 |
||
475 |
static void |
|
476 |
app_section_set_app_info (AppSection *self, |
|
477 |
GDesktopAppInfo *appinfo) |
|
478 |
{
|
|
479 |
AppSectionPrivate *priv = self->priv; |
|
480 |
GFile *desktop_file; |
|
481 |
GError *error = NULL; |
|
482 |
||
483 |
g_return_if_fail (priv->appinfo == NULL); |
|
484 |
g_return_if_fail (priv->desktop_file_monitor == NULL); |
|
485 |
||
486 |
if (appinfo == NULL) { |
|
487 |
g_warning ("appinfo must not be NULL"); |
|
488 |
return; |
|
489 |
}
|
|
490 |
||
491 |
priv->appinfo = g_object_ref (appinfo); |
|
492 |
||
493 |
desktop_file = g_file_new_for_path (g_desktop_app_info_get_filename (appinfo)); |
|
494 |
priv->desktop_file_monitor = g_file_monitor (desktop_file, G_FILE_MONITOR_SEND_MOVED, NULL, &error); |
|
495 |
if (priv->desktop_file_monitor == NULL) { |
|
496 |
g_warning ("unable to watch desktop file: %s", error->message); |
|
497 |
g_error_free (error); |
|
498 |
}
|
|
499 |
g_signal_connect (priv->desktop_file_monitor, "changed", |
|
500 |
G_CALLBACK (desktop_file_changed_cb), self); |
|
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
501 |
|
272.2.29
by Lars Uebernickel
Reexport application actions |
502 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APPINFO]); |
308.1.1
by Lars Uebernickel
Watch desktop files for changes |
503 |
|
504 |
app_section_update_menu (self); |
|
505 |
||
506 |
g_object_unref (desktop_file); |
|
272.2.8
by Lars Uebernickel
Allow creating an app menu item without associated indicate server |
507 |
}
|
508 |
||
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
509 |
AppSection * |
510 |
app_section_new (GDesktopAppInfo *appinfo) |
|
272.2.5
by Lars Uebernickel
Allow creating AppMenuItems without initial listener / server |
511 |
{
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
512 |
return g_object_new (APP_SECTION_TYPE, |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
513 |
"app-info", appinfo, |
514 |
NULL); |
|
272.2.5
by Lars Uebernickel
Allow creating AppMenuItems without initial listener / server |
515 |
}
|
516 |
||
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
517 |
static void |
518 |
activate_cb (GSimpleAction *action, |
|
519 |
GVariant *param, |
|
520 |
gpointer userdata) |
|
521 |
{
|
|
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
522 |
AppSection * mi = APP_SECTION (userdata); |
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
523 |
AppSectionPrivate * priv = mi->priv; |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
524 |
GError *error = NULL; |
340.1.2
by Marco Trevisan (Treviño)
AppSection: use LaunchContext to exec shortcut nicks |
525 |
GAppLaunchContext *launch_context = get_launch_context (g_variant_get_uint32 (param)); |
526 |
||
527 |
if (!g_app_info_launch (G_APP_INFO (priv->appinfo), NULL, launch_context, &error)) { |
|
272.3.11
by Charles Kerr
in app-section.c's activate_cb(), don't leak the GError if we can't launch |
528 |
g_warning("Unable to execute application for desktop file '%s': %s", |
529 |
g_desktop_app_info_get_filename (priv->appinfo), |
|
530 |
error->message); |
|
531 |
g_error_free (error); |
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
532 |
}
|
338.1.2
by Marco Trevisan (Treviño)
AppSection: use the GAppLaunchContext with event timestamp when launching an app |
533 |
|
534 |
g_object_unref (launch_context); |
|
49
by Ted Gould
Adding in an application menu item to start building those |
535 |
}
|
73
by Ted Gould
Adding in an unread count variable, and then a signal to show it chagned. Also, watching for the indicators on this server to make sure it stays correct. |
536 |
|
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
537 |
static void |
538 |
launch_action_change_state (GSimpleAction *action, |
|
539 |
GVariant *value, |
|
540 |
gpointer user_data) |
|
541 |
{
|
|
542 |
g_simple_action_set_state (action, value); |
|
543 |
}
|
|
544 |
||
81
by Ted Gould
Adding functions to make it so that we can get signaled on name changes and also query them in app-menu-items |
545 |
const gchar * |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
546 |
app_section_get_desktop (AppSection * self) |
123.1.20
by Ted Gould
Big commit. Trying to check for eclipses, but first both objects needed to track their desktop file paths. So I had to add that little nugget in as well. |
547 |
{
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
548 |
AppSectionPrivate * priv = self->priv; |
272.2.8
by Lars Uebernickel
Allow creating an app menu item without associated indicate server |
549 |
if (priv->appinfo) |
550 |
return g_desktop_app_info_get_filename (priv->appinfo); |
|
551 |
else
|
|
552 |
return NULL; |
|
123.1.20
by Ted Gould
Big commit. Trying to check for eclipses, but first both objects needed to track their desktop file paths. So I had to add that little nugget in as well. |
553 |
}
|
162.2.2
by Ted Gould
Adding API for getting items |
554 |
|
272.2.29
by Lars Uebernickel
Reexport application actions |
555 |
GActionGroup * |
556 |
app_section_get_actions (AppSection *self) |
|
557 |
{
|
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
558 |
AppSectionPrivate * priv = self->priv; |
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
559 |
return G_ACTION_GROUP (priv->muxer); |
272.2.29
by Lars Uebernickel
Reexport application actions |
560 |
}
|
561 |
||
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
562 |
GMenuModel * |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
563 |
app_section_get_menu (AppSection *self) |
162.2.2
by Ted Gould
Adding API for getting items |
564 |
{
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
565 |
AppSectionPrivate * priv = self->priv; |
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
566 |
return G_MENU_MODEL (priv->menu); |
162.2.2
by Ted Gould
Adding API for getting items |
567 |
}
|
272.2.10
by Lars Uebernickel
Port to gmenu, act I |
568 |
|
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
569 |
GAppInfo * |
272.2.21
by Lars Uebernickel
Rename AppMenuItem to AppSection |
570 |
app_section_get_app_info (AppSection *self) |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
571 |
{
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
572 |
AppSectionPrivate * priv = self->priv; |
272.2.15
by Lars Uebernickel
appmenuitem: make app-info a construct-only property |
573 |
return G_APP_INFO (priv->appinfo); |
574 |
}
|
|
575 |
||
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
576 |
gboolean
|
577 |
app_section_get_draws_attention (AppSection *self) |
|
578 |
{
|
|
579 |
AppSectionPrivate * priv = self->priv; |
|
580 |
return priv->draws_attention; |
|
581 |
}
|
|
582 |
||
272.2.67
by Lars Uebernickel
Make "Clear" work again |
583 |
void
|
584 |
app_section_clear_draws_attention (AppSection *self) |
|
585 |
{
|
|
586 |
AppSectionPrivate * priv = self->priv; |
|
587 |
gchar **action_names; |
|
588 |
gchar **it; |
|
589 |
||
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
590 |
if (priv->source_actions == NULL) |
272.2.67
by Lars Uebernickel
Make "Clear" work again |
591 |
return; |
592 |
||
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
593 |
action_names = g_action_group_list_actions (priv->source_actions); |
272.2.67
by Lars Uebernickel
Make "Clear" work again |
594 |
|
595 |
for (it = action_names; *it; it++) { |
|
596 |
GVariant *state; |
|
597 |
||
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
598 |
state = g_action_group_get_action_state (priv->source_actions, *it); |
272.2.67
by Lars Uebernickel
Make "Clear" work again |
599 |
if (!state) |
600 |
continue; |
|
601 |
||
602 |
/* clear draws-attention while preserving other state */
|
|
603 |
if (action_draws_attention (state)) { |
|
604 |
guint32 count; |
|
605 |
gint64 time; |
|
606 |
const gchar *str; |
|
607 |
GVariant *new_state; |
|
608 |
||
609 |
g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); |
|
610 |
||
611 |
new_state = g_variant_new ("(uxsb)", count, time, str, FALSE); |
|
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
612 |
g_action_group_change_action_state (priv->source_actions, *it, new_state); |
272.2.67
by Lars Uebernickel
Make "Clear" work again |
613 |
}
|
614 |
||
615 |
g_variant_unref (state); |
|
616 |
}
|
|
617 |
||
618 |
g_strfreev (action_names); |
|
619 |
}
|
|
620 |
||
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
621 |
static void |
622 |
application_vanished (GDBusConnection *bus, |
|
623 |
const gchar *name, |
|
624 |
gpointer user_data) |
|
625 |
{
|
|
626 |
AppSection *self = user_data; |
|
627 |
||
628 |
app_section_unset_object_path (self); |
|
629 |
}
|
|
630 |
||
631 |
/*
|
|
632 |
* app_section_set_object_path:
|
|
633 |
* @self: an #AppSection
|
|
634 |
* @bus: a #GDBusConnection
|
|
635 |
* @bus_name: the bus name of the application
|
|
636 |
* @object_path: the object path on which the app exports its actions and menus
|
|
637 |
*
|
|
638 |
* Sets the D-Bus object path exported by an instance of the application
|
|
639 |
* associated with @self. Actions and menus exported on that path will be
|
|
640 |
* shown in the section.
|
|
641 |
*/
|
|
642 |
void
|
|
643 |
app_section_set_object_path (AppSection *self, |
|
644 |
GDBusConnection *bus, |
|
645 |
const gchar *bus_name, |
|
646 |
const gchar *object_path) |
|
647 |
{
|
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
648 |
AppSectionPrivate *priv = self->priv; |
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
649 |
GMenuItem *item; |
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
650 |
|
272.2.54
by Lars Uebernickel
Put launcher and shortcut menu items into the same gmenu section |
651 |
g_object_freeze_notify (G_OBJECT (self)); |
652 |
app_section_unset_object_path (self); |
|
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
653 |
|
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
654 |
priv->source_actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); |
655 |
g_action_muxer_insert (priv->muxer, "source", priv->source_actions); |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
656 |
|
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
657 |
priv->draws_attention = any_action_draws_attention (priv->source_actions, NULL); |
658 |
g_object_connect (priv->source_actions, |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
659 |
"signal::action-added", action_added, self, |
660 |
"signal::action-state-changed", action_state_changed, self, |
|
661 |
"signal::action-removed", action_removed, self, |
|
662 |
NULL); |
|
663 |
||
272.2.88
by Lars Uebernickel
app-section: rename remote_menu to source_menu |
664 |
priv->source_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); |
272.2.25
by Lars Uebernickel
Listen to menus exported by applications |
665 |
|
272.2.88
by Lars Uebernickel
app-section: rename remote_menu to source_menu |
666 |
item = g_menu_item_new_section (NULL, priv->source_menu); |
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
667 |
g_menu_item_set_attribute (item, "action-namespace", "s", "source"); |
668 |
g_menu_append_item (priv->menu, item); |
|
669 |
g_object_unref (item); |
|
272.2.33
by Lars Uebernickel
Reexport application menu as a separate section below the shortcuts |
670 |
|
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
671 |
priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, |
672 |
NULL, application_vanished, |
|
673 |
self, NULL); |
|
272.2.29
by Lars Uebernickel
Reexport application actions |
674 |
|
675 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
676 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
677 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); |
272.2.54
by Lars Uebernickel
Put launcher and shortcut menu items into the same gmenu section |
678 |
g_object_thaw_notify (G_OBJECT (self)); |
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
679 |
|
680 |
g_action_group_change_action_state (G_ACTION_GROUP (priv->static_shortcuts), |
|
681 |
"launch", g_variant_new_boolean (TRUE)); |
|
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
682 |
}
|
683 |
||
684 |
/*
|
|
685 |
* app_section_unset_object_path:
|
|
686 |
* @self: an #AppSection
|
|
687 |
*
|
|
688 |
* Unsets the object path set with app_section_set_object_path(). The section
|
|
689 |
* will return to only showing application name and static shortcuts in the
|
|
690 |
* menu.
|
|
691 |
*/
|
|
692 |
void
|
|
693 |
app_section_unset_object_path (AppSection *self) |
|
694 |
{
|
|
272.2.32
by Lars Uebernickel
app-section: replace G_TYPE_INSTANCE_GET_PRIVATE calls with a priv member |
695 |
AppSectionPrivate *priv = self->priv; |
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
696 |
|
272.2.26
by Lars Uebernickel
app-section: only call g_bus_unwatch_name if we're watching a name |
697 |
if (priv->name_watch_id) { |
272.2.24
by Lars Uebernickel
Listen to actions exported by applications |
698 |
g_bus_unwatch_name (priv->name_watch_id); |
272.2.26
by Lars Uebernickel
app-section: only call g_bus_unwatch_name if we're watching a name |
699 |
priv->name_watch_id = 0; |
700 |
}
|
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
701 |
|
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
702 |
if (priv->source_actions) { |
703 |
g_object_disconnect (priv->source_actions, |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
704 |
"any_signal::action-added", action_added, self, |
705 |
"any_signal::action-state-changed", action_state_changed, self, |
|
706 |
"any_signal::action-removed", action_removed, self, |
|
707 |
NULL); |
|
272.2.87
by Lars Uebernickel
Export both static shortcuts also when the app is running |
708 |
g_clear_object (&priv->source_actions); |
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
709 |
}
|
272.2.33
by Lars Uebernickel
Reexport application menu as a separate section below the shortcuts |
710 |
|
272.2.88
by Lars Uebernickel
app-section: rename remote_menu to source_menu |
711 |
if (priv->source_menu) { |
272.2.54
by Lars Uebernickel
Put launcher and shortcut menu items into the same gmenu section |
712 |
/* the last menu item points is linked to the app's menumodel */
|
713 |
gint n_items = g_menu_model_get_n_items (G_MENU_MODEL (priv->menu)); |
|
714 |
g_menu_remove (priv->menu, n_items -1); |
|
272.2.88
by Lars Uebernickel
app-section: rename remote_menu to source_menu |
715 |
g_clear_object (&priv->source_menu); |
272.2.33
by Lars Uebernickel
Reexport application menu as a separate section below the shortcuts |
716 |
}
|
272.2.29
by Lars Uebernickel
Reexport application actions |
717 |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
718 |
priv->draws_attention = FALSE; |
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
719 |
g_clear_pointer (&priv->chat_status, g_free); |
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
720 |
|
272.2.29
by Lars Uebernickel
Reexport application actions |
721 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); |
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
722 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
723 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); |
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
724 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHAT_STATUS]); |
272.2.86
by Lars Uebernickel
Use a custom menu item for application items |
725 |
|
726 |
g_action_group_change_action_state (G_ACTION_GROUP (priv->static_shortcuts), |
|
727 |
"launch", g_variant_new_boolean (FALSE)); |
|
272.2.66
by Lars Uebernickel
Add draws-attention flag to source actions |
728 |
}
|
729 |
||
730 |
static gboolean |
|
731 |
action_draws_attention (GVariant *state) |
|
732 |
{
|
|
733 |
gboolean attention; |
|
734 |
||
735 |
if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)"))) |
|
736 |
g_variant_get_child (state, 3, "b", &attention); |
|
737 |
else
|
|
738 |
attention = FALSE; |
|
739 |
||
740 |
return attention; |
|
741 |
}
|
|
742 |
||
743 |
static gboolean |
|
744 |
any_action_draws_attention (GActionGroup *group, |
|
745 |
const gchar *ignored_action) |
|
746 |
{
|
|
747 |
gchar **actions; |
|
748 |
gchar **it; |
|
749 |
gboolean attention = FALSE; |
|
750 |
||
751 |
actions = g_action_group_list_actions (group); |
|
752 |
||
753 |
for (it = actions; *it && !attention; it++) { |
|
754 |
GVariant *state; |
|
755 |
||
756 |
if (ignored_action && g_str_equal (ignored_action, *it)) |
|
757 |
continue; |
|
758 |
||
759 |
state = g_action_group_get_action_state (group, *it); |
|
760 |
if (state) { |
|
761 |
attention = action_draws_attention (state); |
|
762 |
g_variant_unref (state); |
|
763 |
}
|
|
764 |
}
|
|
765 |
||
766 |
g_strfreev (actions); |
|
767 |
return attention; |
|
768 |
}
|
|
769 |
||
770 |
static void |
|
771 |
action_added (GActionGroup *group, |
|
772 |
const gchar *action_name, |
|
773 |
gpointer user_data) |
|
774 |
{
|
|
775 |
AppSection *self = user_data; |
|
776 |
GVariant *state; |
|
777 |
||
778 |
state = g_action_group_get_action_state (group, action_name); |
|
779 |
if (state) { |
|
780 |
self->priv->draws_attention |= action_draws_attention (state); |
|
781 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
|
782 |
g_variant_unref (state); |
|
783 |
}
|
|
784 |
}
|
|
785 |
||
786 |
static void |
|
787 |
action_state_changed (GActionGroup *group, |
|
788 |
const gchar *action_name, |
|
789 |
GVariant *value, |
|
790 |
gpointer user_data) |
|
791 |
{
|
|
792 |
AppSection *self = user_data; |
|
793 |
||
794 |
self->priv->draws_attention = any_action_draws_attention (group, NULL); |
|
795 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
|
796 |
}
|
|
797 |
||
798 |
static void |
|
799 |
action_removed (GActionGroup *group, |
|
800 |
const gchar *action_name, |
|
801 |
gpointer user_data) |
|
802 |
{
|
|
803 |
AppSection *self = user_data; |
|
804 |
||
805 |
self->priv->draws_attention = any_action_draws_attention (group, action_name); |
|
806 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); |
|
807 |
}
|
|
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
808 |
|
809 |
gboolean
|
|
810 |
app_section_get_uses_chat_status (AppSection *self) |
|
811 |
{
|
|
812 |
AppSectionPrivate * priv = self->priv; |
|
813 |
||
289
by Lars Uebernickel
Request showing the chat section also when the app is not running |
814 |
return priv->uses_chat_status; |
272.2.76
by Lars Uebernickel
Only show chat section when necessary |
815 |
}
|
313.1.3
by Lars Uebernickel
Set the global chat status more intelligently |
816 |
|
817 |
const gchar * |
|
818 |
app_section_get_status (AppSection *self) |
|
819 |
{
|
|
820 |
AppSectionPrivate * priv = self->priv; |
|
821 |
||
822 |
return priv->chat_status; |
|
823 |
}
|
|
824 |
||
825 |
void
|
|
826 |
app_section_set_status (AppSection *self, |
|
827 |
const gchar *status) |
|
828 |
{
|
|
829 |
AppSectionPrivate * priv = self->priv; |
|
830 |
||
831 |
g_free (priv->chat_status); |
|
832 |
priv->chat_status = g_strdup (status); |
|
833 |
||
834 |
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHAT_STATUS]); |
|
835 |
}
|