1 /* gdkapplaunchcontext.c - Gtk+ implementation for GAppLaunchContext
2
3 Copyright (C) 2007 Red Hat, Inc.
4
5 The Gnome Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The Gnome Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library. If not, see <http://www.gnu.org/licenses/>.
17
18 Author: Alexander Larsson <alexl@redhat.com>
19 */
20
21 #include "config.h"
22
23 #include "gdkapplaunchcontextprivate.h"
24 #include "gdkscreen.h"
25 #include "gdkintl.h"
26
27
28 /**
29 * SECTION:gdkapplaunchcontext
30 * @Short_description: Startup notification for applications
31 * @Title: Application launching
32 *
33 * GdkAppLaunchContext is an implementation of #GAppLaunchContext that
34 * handles launching an application in a graphical context. It provides
35 * startup notification and allows to launch applications on a specific
36 * screen or workspace.
37 *
38 * ## Launching an application
39 *
40 * |[<!-- language="C" -->
41 * GdkAppLaunchContext *context;
42 *
43 * context = gdk_display_get_app_launch_context (display);
44 *
45 * gdk_app_launch_context_set_screen (screen);
46 * gdk_app_launch_context_set_timestamp (event->time);
47 *
48 * if (!g_app_info_launch_default_for_uri ("http://www.gtk.org", context, &error))
49 * g_warning ("Launching failed: %s\n", error->message);
50 *
51 * g_object_unref (context);
52 * ]|
53 */
54
55
56 static void gdk_app_launch_context_finalize (GObject *object);
57 static gchar * gdk_app_launch_context_get_display (GAppLaunchContext *context,
58 GAppInfo *info,
59 GList *files);
60 static gchar * gdk_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
61 GAppInfo *info,
62 GList *files);
63 static void gdk_app_launch_context_launch_failed (GAppLaunchContext *context,
64 const gchar *startup_notify_id);
65
66
67 enum
68 {
69 PROP_0,
70 PROP_DISPLAY
71 };
72
G_DEFINE_TYPE(GdkAppLaunchContext,gdk_app_launch_context,G_TYPE_APP_LAUNCH_CONTEXT)73 G_DEFINE_TYPE (GdkAppLaunchContext, gdk_app_launch_context, G_TYPE_APP_LAUNCH_CONTEXT)
74
75 static void
76 gdk_app_launch_context_get_property (GObject *object,
77 guint prop_id,
78 GValue *value,
79 GParamSpec *pspec)
80 {
81 GdkAppLaunchContext *context = GDK_APP_LAUNCH_CONTEXT (object);
82
83 switch (prop_id)
84 {
85 case PROP_DISPLAY:
86 g_value_set_object (value, context->display);
87 break;
88 default:
89 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
90 }
91 }
92
93 static void
gdk_app_launch_context_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)94 gdk_app_launch_context_set_property (GObject *object,
95 guint prop_id,
96 const GValue *value,
97 GParamSpec *pspec)
98 {
99 GdkAppLaunchContext *context = GDK_APP_LAUNCH_CONTEXT (object);
100
101 switch (prop_id)
102 {
103 case PROP_DISPLAY:
104 context->display = g_value_dup_object (value);
105 break;
106 default:
107 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
108 }
109 }
110
111 static void
gdk_app_launch_context_class_init(GdkAppLaunchContextClass * klass)112 gdk_app_launch_context_class_init (GdkAppLaunchContextClass *klass)
113 {
114 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
115 GAppLaunchContextClass *context_class = G_APP_LAUNCH_CONTEXT_CLASS (klass);
116
117 gobject_class->set_property = gdk_app_launch_context_set_property,
118 gobject_class->get_property = gdk_app_launch_context_get_property;
119
120 gobject_class->finalize = gdk_app_launch_context_finalize;
121
122 context_class->get_display = gdk_app_launch_context_get_display;
123 context_class->get_startup_notify_id = gdk_app_launch_context_get_startup_notify_id;
124 context_class->launch_failed = gdk_app_launch_context_launch_failed;
125
126 g_object_class_install_property (gobject_class, PROP_DISPLAY,
127 g_param_spec_object ("display", P_("Display"), P_("Display"),
128 GDK_TYPE_DISPLAY,
129 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
130 }
131
132 static void
gdk_app_launch_context_init(GdkAppLaunchContext * context)133 gdk_app_launch_context_init (GdkAppLaunchContext *context)
134 {
135 context->workspace = -1;
136 }
137
138 static void
gdk_app_launch_context_finalize(GObject * object)139 gdk_app_launch_context_finalize (GObject *object)
140 {
141 GdkAppLaunchContext *context = GDK_APP_LAUNCH_CONTEXT (object);
142
143 if (context->display)
144 g_object_unref (context->display);
145
146 if (context->screen)
147 g_object_unref (context->screen);
148
149 if (context->icon)
150 g_object_unref (context->icon);
151
152 g_free (context->icon_name);
153
154 G_OBJECT_CLASS (gdk_app_launch_context_parent_class)->finalize (object);
155 }
156
157 static gchar *
gdk_app_launch_context_get_display(GAppLaunchContext * context,GAppInfo * info,GList * files)158 gdk_app_launch_context_get_display (GAppLaunchContext *context,
159 GAppInfo *info,
160 GList *files)
161 {
162 GdkAppLaunchContext *ctx = GDK_APP_LAUNCH_CONTEXT (context);
163 GdkDisplay *display;
164
165 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
166 if (ctx->screen)
167 return gdk_screen_make_display_name (ctx->screen);
168 G_GNUC_END_IGNORE_DEPRECATIONS
169
170 if (ctx->display)
171 display = ctx->display;
172 else
173 display = gdk_display_get_default ();
174
175 return g_strdup (gdk_display_get_name (display));
176 }
177
178 /**
179 * gdk_app_launch_context_set_display:
180 * @context: a #GdkAppLaunchContext
181 * @display: a #GdkDisplay
182 *
183 * Sets the display on which applications will be launched when
184 * using this context. See also gdk_app_launch_context_set_screen().
185 *
186 * Since: 2.14
187 *
188 * Deprecated: 3.0: Use gdk_display_get_app_launch_context() instead
189 */
190 void
gdk_app_launch_context_set_display(GdkAppLaunchContext * context,GdkDisplay * display)191 gdk_app_launch_context_set_display (GdkAppLaunchContext *context,
192 GdkDisplay *display)
193 {
194 g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context));
195 g_return_if_fail (display == NULL || GDK_IS_DISPLAY (display));
196
197 g_warn_if_fail (display == NULL || display == context->display);
198 }
199
200 /**
201 * gdk_app_launch_context_set_screen:
202 * @context: a #GdkAppLaunchContext
203 * @screen: a #GdkScreen
204 *
205 * Sets the screen on which applications will be launched when
206 * using this context. See also gdk_app_launch_context_set_display().
207 *
208 * If both @screen and @display are set, the @screen takes priority.
209 * If neither @screen or @display are set, the default screen and
210 * display are used.
211 *
212 * Since: 2.14
213 */
214 void
gdk_app_launch_context_set_screen(GdkAppLaunchContext * context,GdkScreen * screen)215 gdk_app_launch_context_set_screen (GdkAppLaunchContext *context,
216 GdkScreen *screen)
217 {
218 g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context));
219 g_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
220
221 g_return_if_fail (screen == NULL || gdk_screen_get_display (screen) == context->display);
222
223 if (context->screen)
224 {
225 g_object_unref (context->screen);
226 context->screen = NULL;
227 }
228
229 if (screen)
230 context->screen = g_object_ref (screen);
231 }
232
233 /**
234 * gdk_app_launch_context_set_desktop:
235 * @context: a #GdkAppLaunchContext
236 * @desktop: the number of a workspace, or -1
237 *
238 * Sets the workspace on which applications will be launched when
239 * using this context when running under a window manager that
240 * supports multiple workspaces, as described in the
241 * [Extended Window Manager Hints](http://www.freedesktop.org/Standards/wm-spec).
242 *
243 * When the workspace is not specified or @desktop is set to -1,
244 * it is up to the window manager to pick one, typically it will
245 * be the current workspace.
246 *
247 * Since: 2.14
248 */
249 void
gdk_app_launch_context_set_desktop(GdkAppLaunchContext * context,gint desktop)250 gdk_app_launch_context_set_desktop (GdkAppLaunchContext *context,
251 gint desktop)
252 {
253 g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context));
254
255 context->workspace = desktop;
256 }
257
258 /**
259 * gdk_app_launch_context_set_timestamp:
260 * @context: a #GdkAppLaunchContext
261 * @timestamp: a timestamp
262 *
263 * Sets the timestamp of @context. The timestamp should ideally
264 * be taken from the event that triggered the launch.
265 *
266 * Window managers can use this information to avoid moving the
267 * focus to the newly launched application when the user is busy
268 * typing in another window. This is also known as 'focus stealing
269 * prevention'.
270 *
271 * Since: 2.14
272 */
273 void
gdk_app_launch_context_set_timestamp(GdkAppLaunchContext * context,guint32 timestamp)274 gdk_app_launch_context_set_timestamp (GdkAppLaunchContext *context,
275 guint32 timestamp)
276 {
277 g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context));
278
279 context->timestamp = timestamp;
280 }
281
282 /**
283 * gdk_app_launch_context_set_icon:
284 * @context: a #GdkAppLaunchContext
285 * @icon: (allow-none): a #GIcon, or %NULL
286 *
287 * Sets the icon for applications that are launched with this
288 * context.
289 *
290 * Window Managers can use this information when displaying startup
291 * notification.
292 *
293 * See also gdk_app_launch_context_set_icon_name().
294 *
295 * Since: 2.14
296 */
297 void
gdk_app_launch_context_set_icon(GdkAppLaunchContext * context,GIcon * icon)298 gdk_app_launch_context_set_icon (GdkAppLaunchContext *context,
299 GIcon *icon)
300 {
301 g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context));
302 g_return_if_fail (icon == NULL || G_IS_ICON (icon));
303
304 if (context->icon)
305 {
306 g_object_unref (context->icon);
307 context->icon = NULL;
308 }
309
310 if (icon)
311 context->icon = g_object_ref (icon);
312 }
313
314 /**
315 * gdk_app_launch_context_set_icon_name:
316 * @context: a #GdkAppLaunchContext
317 * @icon_name: (allow-none): an icon name, or %NULL
318 *
319 * Sets the icon for applications that are launched with this context.
320 * The @icon_name will be interpreted in the same way as the Icon field
321 * in desktop files. See also gdk_app_launch_context_set_icon().
322 *
323 * If both @icon and @icon_name are set, the @icon_name takes priority.
324 * If neither @icon or @icon_name is set, the icon is taken from either
325 * the file that is passed to launched application or from the #GAppInfo
326 * for the launched application itself.
327 *
328 * Since: 2.14
329 */
330 void
gdk_app_launch_context_set_icon_name(GdkAppLaunchContext * context,const char * icon_name)331 gdk_app_launch_context_set_icon_name (GdkAppLaunchContext *context,
332 const char *icon_name)
333 {
334 g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context));
335
336 g_free (context->icon_name);
337 context->icon_name = g_strdup (icon_name);
338 }
339
340 /**
341 * gdk_app_launch_context_new:
342 *
343 * Creates a new #GdkAppLaunchContext.
344 *
345 * Returns: a new #GdkAppLaunchContext
346 *
347 * Since: 2.14
348 *
349 * Deprecated: 3.0: Use gdk_display_get_app_launch_context() instead
350 */
351 GdkAppLaunchContext *
gdk_app_launch_context_new(void)352 gdk_app_launch_context_new (void)
353 {
354 return gdk_display_get_app_launch_context (gdk_display_get_default ());
355 }
356
357 static char *
gdk_app_launch_context_get_startup_notify_id(GAppLaunchContext * context,GAppInfo * info,GList * files)358 gdk_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
359 GAppInfo *info,
360 GList *files)
361 {
362 return NULL;
363 }
364
365 static void
gdk_app_launch_context_launch_failed(GAppLaunchContext * context,const gchar * startup_notify_id)366 gdk_app_launch_context_launch_failed (GAppLaunchContext *context,
367 const gchar *startup_notify_id)
368 {
369 }
370