]>
Dogcows Code - chaz/openbox/blob - plugins/placement/history.c
9d932b9edfbe7e0ca292738f298f91ae0d6782ce
1 #include "kernel/openbox.h"
2 #include "kernel/dispatch.h"
3 #include "kernel/frame.h"
4 #include "kernel/client.h"
5 #include "kernel/screen.h"
6 #include "kernel/parse.h"
14 #define PLACED (1 << 0)
16 #define HAVE_POSITION (1 << 1)
17 #define HAVE_SIZE (1 << 2)
18 #define HAVE_DESKTOP (1 << 3)
32 static GSList
*history_list
= NULL
;
33 static char *history_path
= NULL
;
35 static struct HistoryItem
*history_find(const char *name
, const char *class,
39 struct HistoryItem
*hi
= NULL
;
42 for (it
= history_list
; it
!= NULL
; it
= it
->next
) {
44 if (!g_utf8_collate(hi
->name
, name
) &&
45 !g_utf8_collate(hi
->class, class) &&
46 !g_utf8_collate(hi
->role
, role
))
52 gboolean
place_history(Client
*c
)
54 struct HistoryItem
*hi
;
57 hi
= history_find(c
->name
, c
->class, c
->role
);
59 if (hi
&& !(hi
->flags
& PLACED
)) {
61 if (ob_state
!= State_Starting
) {
62 if (hi
->flags
& HAVE_POSITION
||
63 hi
->flags
& HAVE_SIZE
) {
64 if (hi
->flags
& HAVE_POSITION
) {
67 /* get where the client should be */
68 frame_frame_gravity(c
->frame
, &x
, &y
);
73 if (hi
->flags
& HAVE_SIZE
) {
74 w
= hi
->w
* c
->size_inc
.width
;
75 h
= hi
->h
* c
->size_inc
.height
;
80 client_configure(c
, Corner_TopLeft
, x
, y
, w
, h
,
83 if (hi
->flags
& HAVE_DESKTOP
) {
84 client_set_desktop(c
, hi
->desk
, FALSE
);
87 return hi
->flags
& HAVE_POSITION
;
93 static void set_history(Client
*c
)
95 struct HistoryItem
*hi
;
97 hi
= history_find(c
->name
, c
->class, c
->role
);
100 hi
= g_new(struct HistoryItem
, 1);
101 history_list
= g_slist_append(history_list
, hi
);
102 hi
->name
= g_strdup(c
->name
);
103 hi
->class = g_strdup(c
->class);
104 hi
->role
= g_strdup(c
->role
);
105 hi
->flags
= HAVE_POSITION
;
108 if (hi
->flags
& HAVE_POSITION
) {
109 hi
->x
= c
->frame
->area
.x
;
110 hi
->y
= c
->frame
->area
.y
;
113 hi
->flags
&= ~PLACED
;
116 static void event(ObEvent
*e
, void *foo
)
118 g_assert(e
->type
== Event_Client_Destroy
);
120 set_history(e
->data
.c
.client
);
125 <entry name="name" class="class" role="role">
135 static void save_history()
138 xmlNodePtr root
, node
;
142 doc
= xmlNewDoc(NULL
);
143 root
= xmlNewNode(NULL
, (const xmlChar
*) "openbox_history");
144 xmlDocSetRootElement(doc
, root
);
146 for (it
= history_list
; it
; it
= g_slist_next(it
)) {
147 struct HistoryItem
*hi
= it
->data
;
148 g_message("adding %s", hi
->name
);
149 node
= xmlNewChild(root
, NULL
, (const xmlChar
*) "entry", NULL
);
150 xmlNewProp(node
, (const xmlChar
*) "name", (const xmlChar
*) hi
->name
);
151 xmlNewProp(node
, (const xmlChar
*) "class", (const xmlChar
*) hi
->class);
152 xmlNewProp(node
, (const xmlChar
*) "role", (const xmlChar
*) hi
->role
);
153 if (hi
->flags
& HAVE_POSITION
) {
154 s
= g_strdup_printf("%d", hi
->x
);
155 xmlNewTextChild(node
, NULL
,
156 (const xmlChar
*) "x", (const xmlChar
*) s
);
158 s
= g_strdup_printf("%d", hi
->y
);
159 xmlNewTextChild(node
, NULL
,
160 (const xmlChar
*) "y", (const xmlChar
*) s
);
163 if (hi
->flags
& HAVE_SIZE
) {
164 s
= g_strdup_printf("%d", hi
->w
);
165 xmlNewTextChild(node
, NULL
,
166 (const xmlChar
*) "width", (const xmlChar
*) s
);
168 s
= g_strdup_printf("%d", hi
->h
);
169 xmlNewTextChild(node
, NULL
,
170 (const xmlChar
*) "height", (const xmlChar
*) s
);
173 if (hi
->flags
& HAVE_DESKTOP
) {
174 s
= g_strdup_printf("%d", hi
->desk
< 0 ? hi
->desk
: hi
->desk
+ 1);
175 xmlNewTextChild(node
, NULL
,
176 (const xmlChar
*) "desktop", (const xmlChar
*) s
);
181 xmlIndentTreeOutput
= 1;
182 xmlSaveFormatFile(history_path
, doc
, 1);
187 static void load_history()
194 struct HistoryItem
*hi
;
196 if (!(doc
= xmlParseFile(history_path
)))
198 if (!(node
= xmlDocGetRootElement(doc
))) {
203 if (xmlStrcasecmp(node
->name
, (const xmlChar
*)"openbox_history")) {
209 node
= parse_find_node("entry", node
->xmlChildrenNode
);
211 name
= class = role
= NULL
;
212 if (parse_attr_string("name", node
, &name
) &&
213 parse_attr_string("class", node
, &class) &&
214 parse_attr_string("role", node
, &role
)) {
216 hi
= history_find(name
, class, role
);
218 hi
= g_new(struct HistoryItem
, 1);
219 hi
->name
= g_strdup(name
);
220 hi
->class = g_strdup(class);
221 hi
->role
= g_strdup(role
);
224 if ((n
= parse_find_node("x", node
->xmlChildrenNode
))) {
225 hi
->x
= parse_int(doc
, n
);
226 if ((n
= parse_find_node("y", node
->xmlChildrenNode
))) {
227 hi
->y
= parse_int(doc
, n
);
228 hi
->flags
|= HAVE_POSITION
;
231 if ((n
= parse_find_node("width", node
->xmlChildrenNode
))) {
232 hi
->w
= parse_int(doc
, n
);
233 if ((n
= parse_find_node("height", node
->xmlChildrenNode
))) {
234 hi
->h
= parse_int(doc
, n
);
235 hi
->flags
|= HAVE_SIZE
;
238 if ((n
= parse_find_node("desktop", node
->xmlChildrenNode
))) {
239 hi
->desk
= parse_int(doc
, n
);
240 if (hi
->desk
> 0) --hi
->desk
;
241 hi
->flags
|= HAVE_DESKTOP
;
244 history_list
= g_slist_append(history_list
, hi
);
246 g_free(name
); g_free(class); g_free(role
);
247 node
= parse_find_node("entry", node
->next
);
252 void history_startup()
258 path
= g_build_filename(g_get_home_dir(), ".openbox", "history", NULL
);
259 history_path
= g_strdup_printf("%s.%d", path
, ob_screen
);
262 load_history(); /* load from the historydb file */
264 dispatch_register(Event_Client_Destroy
, (EventHandler
)event
, NULL
);
267 void history_shutdown()
271 save_history(); /* save to the historydb file */
272 for (it
= history_list
; it
!= NULL
; it
= it
->next
) {
273 struct HistoryItem
*hi
= it
->data
;
279 g_slist_free(history_list
);
281 dispatch_register(0, (EventHandler
)event
, NULL
);
283 g_free(history_path
);
This page took 0.045267 seconds and 4 git commands to generate.