]> Dogcows Code - chaz/openbox/blob - obt/link.c
Fix maximized windows and such after screen resizings
[chaz/openbox] / obt / link.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3 obt/link.c for the Openbox window manager
4 Copyright (c) 2009 Dana Jansens
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 See the COPYING file for a copy of the GNU General Public License.
17 */
18
19 #include "obt/link.h"
20 #include "obt/ddparse.h"
21 #include "obt/paths.h"
22 #include <glib.h>
23
24 struct _ObtLink {
25 guint ref;
26
27 ObtLinkType type;
28 gchar *name; /*!< Specific name for the object (eg Firefox) */
29 gboolean display; /*<! When false, do not display this link in menus or
30 launchers, etc */
31 gboolean deleted; /*<! When true, the Link could exist but is deleted
32 for the current user */
33 gchar *generic; /*!< Generic name for the object (eg Web Browser) */
34 gchar *comment; /*!< Comment/description to display for the object */
35 gchar *icon; /*!< Name/path for an icon for the object */
36 guint env_required; /*!< The environments that must be present to use this
37 link. */
38 guint env_restricted; /*!< The environments that must _not_ be present to
39 use this link. */
40
41 union _ObtLinkData {
42 struct _ObtLinkApp {
43 gchar *exec; /*!< Executable to run for the app */
44 gchar *wdir; /*!< Working dir to run the app in */
45 gboolean term; /*!< Run the app in a terminal or not */
46 ObtLinkAppOpen open;
47
48 gchar **mime; /*!< Mime types the app can open */
49
50 GQuark *categories; /*!< Array of quarks representing the
51 application's categories */
52 gulong n_categories; /*!< Number of categories for the app */
53
54 ObtLinkAppStartup startup;
55 gchar *startup_wmclass;
56 } app;
57 struct _ObtLinkLink {
58 gchar *addr;
59 } url;
60 struct _ObtLinkDir {
61 } dir;
62 } d;
63 };
64
65 ObtLink* obt_link_from_ddfile(const gchar *ddname, GSList *paths,
66 ObtPaths *p)
67 {
68 ObtLink *link;
69 GHashTable *groups, *keys;
70 ObtDDParseGroup *g;
71 ObtDDParseValue *v;
72
73 /* parse the file, and get a hash table of the groups */
74 groups = obt_ddparse_file(ddname, paths);
75 if (!groups) return NULL; /* parsing failed */
76 /* grab the Desktop Entry group */
77 g = g_hash_table_lookup(groups, "Desktop Entry");
78 g_assert(g != NULL);
79 /* grab the keys that appeared in the Desktop Entry group */
80 keys = obt_ddparse_group_keys(g);
81
82 /* build the ObtLink (we steal all strings from the parser) */
83 link = g_slice_new0(ObtLink);
84 link->ref = 1;
85 link->display = TRUE;
86
87 v = g_hash_table_lookup(keys, "Type");
88 g_assert(v);
89 link->type = v->value.enumerable;
90
91 if ((v = g_hash_table_lookup(keys, "Hidden")))
92 link->deleted = v->value.boolean;
93
94 if ((v = g_hash_table_lookup(keys, "NoDisplay")))
95 link->display = !v->value.boolean;
96
97 if ((v = g_hash_table_lookup(keys, "GenericName")))
98 link->generic = v->value.string, v->value.string = NULL;
99
100 if ((v = g_hash_table_lookup(keys, "Comment")))
101 link->comment = v->value.string, v->value.string = NULL;
102
103 if ((v = g_hash_table_lookup(keys, "Icon")))
104 link->icon = v->value.string, v->value.string = NULL;
105
106 if ((v = g_hash_table_lookup(keys, "OnlyShowIn")))
107 link->env_required = v->value.environments;
108 else
109 link->env_required = 0;
110
111 if ((v = g_hash_table_lookup(keys, "NotShowIn")))
112 link->env_restricted = v->value.environments;
113 else
114 link->env_restricted = 0;
115
116 /* type-specific keys */
117
118 if (link->type == OBT_LINK_TYPE_APPLICATION) {
119 gchar *c;
120 gboolean percent;
121
122 v = g_hash_table_lookup(keys, "Exec");
123 g_assert(v);
124 link->d.app.exec = v->value.string;
125 v->value.string = NULL;
126
127 /* parse link->d.app.exec to determine link->d.app.open */
128 percent = FALSE;
129 for (c = link->d.app.exec; *c; ++c) {
130 if (percent) {
131 switch (*c) {
132 case 'f': link->d.app.open = OBT_LINK_APP_SINGLE_LOCAL; break;
133 case 'F': link->d.app.open = OBT_LINK_APP_MULTI_LOCAL; break;
134 case 'u': link->d.app.open = OBT_LINK_APP_SINGLE_URL; break;
135 case 'U': link->d.app.open = OBT_LINK_APP_MULTI_URL; break;
136 default: percent = FALSE;
137 }
138 if (percent) break; /* found f/F/u/U */
139 }
140 else if (*c == '%') percent = TRUE;
141 }
142
143 if ((v = g_hash_table_lookup(keys, "TryExec"))) {
144 /* XXX spawn a thread to check TryExec? */
145 link->display = link->display &&
146 obt_paths_try_exec(p, v->value.string);
147 }
148
149 if ((v = g_hash_table_lookup(keys, "Path"))) {
150 /* steal the string */
151 link->d.app.wdir = v->value.string;
152 v->value.string = NULL;
153 }
154
155 if ((v = g_hash_table_lookup(keys, "Terminal")))
156 link->d.app.term = v->value.boolean;
157
158 if ((v = g_hash_table_lookup(keys, "StartupNotify")))
159 link->d.app.startup = v->value.boolean ?
160 OBT_LINK_APP_STARTUP_PROTOCOL_SUPPORT :
161 OBT_LINK_APP_STARTUP_NO_SUPPORT;
162 else {
163 link->d.app.startup = OBT_LINK_APP_STARTUP_LEGACY_SUPPORT;
164 if ((v = g_hash_table_lookup(keys, "StartupWMClass"))) {
165 /* steal the string */
166 link->d.app.startup_wmclass = v->value.string;
167 v->value.string = NULL;
168 }
169 }
170
171 if ((v = g_hash_table_lookup(keys, "Categories"))) {
172 gulong i;
173 gchar *end;
174
175 link->d.app.categories = g_new(GQuark, v->value.strings.n);
176 link->d.app.n_categories = v->value.strings.n;
177
178 for (i = 0; i < v->value.strings.n; ++i) {
179 link->d.app.categories[i] =
180 g_quark_from_string(v->value.strings.a[i]);
181 c = end = end+1; /* next */
182 }
183 }
184
185 if ((v = g_hash_table_lookup(keys, "MimeType"))) {
186 /* steal the string array */
187 link->d.app.mime = v->value.strings.a;
188 v->value.strings.a = NULL;
189 v->value.strings.n = 0;
190 }
191 }
192 else if (link->type == OBT_LINK_TYPE_URL) {
193 v = g_hash_table_lookup(keys, "URL");
194 g_assert(v);
195 link->d.url.addr = v->value.string;
196 v->value.string = NULL;
197 }
198
199 /* destroy the parsing info */
200 g_hash_table_destroy(groups);
201
202 return link;
203 }
204
205 void obt_link_ref(ObtLink *dd)
206 {
207 ++dd->ref;
208 }
209
210 void obt_link_unref(ObtLink *dd)
211 {
212 if (--dd->ref < 1) {
213 g_free(dd->name);
214 g_free(dd->generic);
215 g_free(dd->comment);
216 g_free(dd->icon);
217 if (dd->type == OBT_LINK_TYPE_APPLICATION) {
218 g_free(dd->d.app.exec);
219 g_free(dd->d.app.wdir);
220 g_strfreev(dd->d.app.mime);
221 g_free(dd->d.app.categories);
222 g_free(dd->d.app.startup_wmclass);
223 }
224 else if (dd->type == OBT_LINK_TYPE_URL)
225 g_free(dd->d.url.addr);
226 g_slice_free(ObtLink, dd);
227 }
228 }
229
230 const GQuark* obt_link_app_categories(ObtLink *e, gulong *n)
231 {
232 g_return_val_if_fail(e != NULL, NULL);
233 g_return_val_if_fail(e->type == OBT_LINK_TYPE_APPLICATION, NULL);
234 g_return_val_if_fail(n != NULL, NULL);
235
236 *n = e->d.app.n_categories;
237 return e->d.app.categories;
238 }
This page took 0.046785 seconds and 4 git commands to generate.