]>
Dogcows Code - chaz/openbox/blob - plugins/placement/history.c
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 "parser/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 (!strcmp(hi
->name
, name
) &&
45 !strcmp(hi
->class, class) &&
46 !strcmp(hi
->role
, role
))
52 gboolean
place_history(ObClient
*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() != OB_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
, OB_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(ObClient
*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 (!parse_load(history_path
, "openbox_history", &doc
, &node
))
199 node
= parse_find_node("entry", node
->xmlChildrenNode
);
201 name
= class = role
= NULL
;
202 if (parse_attr_string("name", node
, &name
) &&
203 parse_attr_string("class", node
, &class) &&
204 parse_attr_string("role", node
, &role
)) {
206 hi
= history_find(name
, class, role
);
208 hi
= g_new(struct HistoryItem
, 1);
209 hi
->name
= g_strdup(name
);
210 hi
->class = g_strdup(class);
211 hi
->role
= g_strdup(role
);
214 if ((n
= parse_find_node("x", node
->xmlChildrenNode
))) {
215 hi
->x
= parse_int(doc
, n
);
216 if ((n
= parse_find_node("y", node
->xmlChildrenNode
))) {
217 hi
->y
= parse_int(doc
, n
);
218 hi
->flags
|= HAVE_POSITION
;
221 if ((n
= parse_find_node("width", node
->xmlChildrenNode
))) {
222 hi
->w
= parse_int(doc
, n
);
223 if ((n
= parse_find_node("height", node
->xmlChildrenNode
))) {
224 hi
->h
= parse_int(doc
, n
);
225 hi
->flags
|= HAVE_SIZE
;
228 if ((n
= parse_find_node("desktop", node
->xmlChildrenNode
))) {
229 hi
->desk
= parse_int(doc
, n
);
230 if (hi
->desk
> 0) --hi
->desk
;
231 hi
->flags
|= HAVE_DESKTOP
;
234 history_list
= g_slist_append(history_list
, hi
);
236 g_free(name
); g_free(class); g_free(role
);
237 node
= parse_find_node("entry", node
->next
);
242 void history_startup()
248 path
= g_build_filename(g_get_home_dir(), ".openbox", "history", NULL
);
249 history_path
= g_strdup_printf("%s.%d", path
, ob_screen
);
252 load_history(); /* load from the historydb file */
254 dispatch_register(Event_Client_Destroy
, (EventHandler
)event
, NULL
);
257 void history_shutdown()
261 save_history(); /* save to the historydb file */
262 for (it
= history_list
; it
!= NULL
; it
= it
->next
) {
263 struct HistoryItem
*hi
= it
->data
;
269 g_slist_free(history_list
);
271 dispatch_register(0, (EventHandler
)event
, NULL
);
273 g_free(history_path
);
This page took 0.049789 seconds and 4 git commands to generate.