4 * Copyright (c) Tuomo Valkonen 1999-2001.
5 * See the included file LICENSE for details.
15 #include "clientwin.h"
25 static void client_remove_child(WClient
*client
, WThing
*thing
);
27 static WThingFuntab client_funtab
={
32 IMPLOBJ(WClient
, WThing
, &client_funtab
)
35 /*{{{ Create/destroy */
38 static bool init_client(WClient
*client
)
40 LINK_ITEM(wglobal
.client_list
, client
, g_client_next
, g_client_prev
);
42 client
->thing
.flags
|=WTHING_DESTREMPTY
;
43 client
->label_next
=client
;
44 client
->label_prev
=client
;
50 WClient
*create_client(WScreen
*scr
)
52 CREATETHING_IMPL(WClient
, client
, scr
, (p
));
56 void deinit_client(WClient
*client
)
58 client_unuse_label(client
);
59 UNLINK_ITEM(wglobal
.client_list
, client
, g_client_next
, g_client_prev
);
60 if(client
->label
!=NULL
)
68 /*{{{ Add/remove clientwin */
71 void client_add_clientwin(WClient
*client
, WClientWin
*cwin
)
73 link_thing((WThing
*)client
, (WThing
*)cwin
);
75 if(FIRST_THING(client
, WClientWin
)==cwin
)
76 client_use_label(client
);
78 if(CLIENT_HAS_FRAME(client
))
79 frame_add_clientwin(CLIENT_FRAME(client
), client
, cwin
);
83 static void client_remove_child(WClient
*client
, WThing
*thing
)
88 if(!WTHING_IS(thing
, WClientWin
))
91 frame
=FIND_PARENT(client
, WFrame
);
93 if(frame
==NULL
|| !IS_ACTIVE_FRAME(frame
))
96 if(frame
->current_client
!=client
)
100 n
=LAST_THING(client
, WClientWin
);
102 set_focus((WThing
*)n
);
109 /*{{{ Clientwin wrappers */
112 void hide_client(WClient
*client
)
116 FOR_ALL_TYPED(client
, cwin
, WClientWin
){
117 hide_clientwin(cwin
);
122 void show_client(WClient
*client
)
124 WClientWin
*cwin
, *first
;
126 FOR_ALL_TYPED(client
, cwin
, WClientWin
){
127 show_clientwin(cwin
);
132 void focus_client(WClient
*client
)
134 WClientWin
*cwin
=LAST_THING(client
, WClientWin
);
137 focus_clientwin(cwin
);
141 void close_client(WClient
*client
)
143 WClientWin
*cwin
=LAST_THING(client
, WClientWin
);
146 close_clientwin(cwin
);
150 void close_client_main(WClient
*client
)
152 WClientWin
*cwin
=FIRST_THING(client
, WClientWin
);
155 close_clientwin(cwin
);
159 void kill_client(WClient
*client
)
161 WClientWin
*cwin
=FIRST_THING(client
, WClientWin
);
164 kill_clientwin(cwin
);
171 /*{{{ Reparent/fit/reconf */
174 void reparent_client(WClient
*client
, Window win
, int x
, int y
)
178 FOR_ALL_TYPED(client
, cwin
, WClientWin
){
179 reparent_clientwin(cwin
, win
, x
, y
);
184 void fit_client_frame(WClient
*client
, WFrame
*frame
)
188 FOR_ALL_TYPED(client
, cwin
, WClientWin
){
189 fit_clientwin_frame(cwin
, frame
);
194 void reparent_fit_client_frame(WClient
*client
, WFrame
*frame
)
198 FOR_ALL_TYPED(client
, cwin
, WClientWin
){
199 reparent_fit_clientwin_frame(cwin
, frame
);
204 void reconf_client_frame(WClient
*client
, WFrame
*frame
)
208 FOR_ALL_TYPED(client
, cwin
, WClientWin
){
209 reconf_clientwin_frame(cwin
, frame
);
220 static char *untitled_label
="<untitled>";
221 static char *empty_label
="<empty>";
224 static const char *client_beg_label(WClient
*client
)
226 WClientWin
*cwin
=FIRST_THING(client
, WClientWin
);
233 /*else if(cwin->icon_name!=NULL)
234 return cwin->icon_name;*/
236 return untitled_label
;
240 #define CLIENTNUM_TMPL "<%d>"
242 void client_make_label(WClient
*client
, int maxw
)
244 const char *str
=client_beg_label(client
);
248 if(client
->label_inst
!=0)
249 sprintf(tmp
, CLIENTNUM_TMPL
, client
->label_inst
);
253 if(client
->label
!=NULL
)
256 grdata
=GRDATA_OF(client
);
258 client
->label
=make_label(grdata
->tab_font
, str
, tmp
, maxw
, NULL
);
262 char *client_full_label(WClient
*client
)
264 const char *str
=client_beg_label(client
);
267 if(client
->label_inst
!=0){
268 sprintf(tmp
, CLIENTNUM_TMPL
, client
->label_inst
);
269 return scat(str
, tmp
);
276 static void use_label(WClient
*client
, const char *label
)
278 WClient
*p
, *np
, *minp
=NULL
;
282 for(p
=wglobal
.client_list
; p
!=NULL
; p
=p
->g_client_next
){
285 str
=client_beg_label(p
);
286 if(strcmp(str
, label
)==0)
296 if(p
->label_inst
+1==np
->label_inst
){
298 }else if(p
->label_inst
>=np
->label_inst
&& np
->label_inst
!=0){
301 }else if(p
->label_inst
+1<mininst
){
302 mininst
=p
->label_inst
+1;
312 client
->label_next
=np
;
313 np
->label_prev
=client
;
314 minp
->label_next
=client
;
315 client
->label_prev
=minp
;
316 client
->label_inst
=mininst
;
320 void client_use_label(WClient
*client
)
323 const char *p
=client_beg_label(client
);
325 use_label(client
, p
);
327 frame
=FIND_PARENT(client
, WFrame
);
330 frame_recalc_bar(frame
);
334 void client_unuse_label(WClient
*client
)
336 client
->label_next
->label_prev
=client
->label_prev
;
337 client
->label_prev
->label_next
=client
->label_next
;
338 client
->label_next
=client
;
339 client
->label_prev
=client
;
340 client
->label_inst
=0;
350 void client_toggle_tagged(WClient
*client
)
353 client
->flags
^=CLIENT_TAGGED
;
355 if(CLIENT_HAS_FRAME(client
))
356 draw_frame_bar(CLIENT_FRAME(client
), FALSE
);
364 for(client
=wglobal
.client_list
; client
!=NULL
; client
=client
->g_client_next
){
365 if(!(client
->flags
&CLIENT_TAGGED
))
367 client
->flags
&=~CLIENT_TAGGED
;
368 if(CLIENT_HAS_FRAME(client
))
369 draw_frame_bar(CLIENT_FRAME(client
), FALSE
);
374 void set_client_frame_id(WClient
*client
, int id
)
376 WClientWin
*cwin
=FIRST_THING(client
, WClientWin
);
378 set_integer_property(cwin
->win
, wglobal
.atom_frame_id
, id
);
382 bool goto_window(WWindow
*wwin
)
386 if(wglobal
.current_wswindow
==wwin
)
389 ws
=FIND_PARENT(wwin
, WWorkspace
);
394 set_previous((WThing
*)wwin
);
397 if(!active_workspace(ws
))
398 switch_workspace(ws
);
402 unprotect_previous();
408 void goto_client(WClient
*client
)
410 WFrame
*frame
=FIND_PARENT(client
, WFrame
);
415 set_previous((WThing
*)client
);
418 goto_window((WWindow
*)frame
);
420 if(frame
->current_client
!=client
)
421 frame_switch_client(frame
, client
);
423 unprotect_previous();
429 WThing
*t
=wglobal
.previous
;
434 if(WTHING_IS(t
, WClient
))
435 goto_client((WClient
*)t
);
436 else if(WTHING_IS(t
, WWindow
))
437 goto_window((WWindow
*)t
);
440 bool goto_client_name(const char *cname
)
442 WClient
*client
=lookup_client(cname
);
458 WClient
*lookup_client(const char *cname
)
463 for(client
=wglobal
.client_list
;
465 client
=client
->g_client_next
){
467 name
=client_full_label(client
);
471 if(strcmp(name
, cname
)){
485 int complete_client(char *nam
, char ***cp_ret
, char **beg
)
490 int n
=0, l
=strlen(nam
);
497 for(client
=wglobal
.client_list
;
499 client
=client
->g_client_next
){
501 name
=(char*)client_full_label(client
);
505 if((lnum
==0 && l
&& strncmp(name
, nam
, l
)) ||
506 (strstr(name
, nam
)==NULL
)){
511 if(!add_to_complist(cp_ret
, &n
, name
))
515 if(n
==0 && lnum
==0 && l
>1){