1/*
2 * Functions related to icon managers and the workspace manager.
3 */
4
5#include "ctwm.h"
6
7#include "functions_internal.h"
8#include "iconmgr.h"
9#include "icons.h"
10#include "otp.h"
11#include "screen.h"
12#include "vscreen.h"
13#include "win_iconify.h"
14#include "win_utils.h"
15#include "workspace_manager.h"
16
17
18/*
19 * Moving around in the icon manager.
20 *
21 * XXX These backend funcs in iconmgr.c are passed func directly.  That's
22 * a bit of a layering violation; they should maybe be changed to have
23 * their own idea of directionality...
24 */
25DFHANDLER(upiconmgr)
26{
27	MoveIconManager(func);
28}
29DFHANDLER(downiconmgr)
30{
31	MoveIconManager(func);
32}
33DFHANDLER(lefticonmgr)
34{
35	MoveIconManager(func);
36}
37DFHANDLER(righticonmgr)
38{
39	MoveIconManager(func);
40}
41DFHANDLER(forwiconmgr)
42{
43	MoveIconManager(func);
44}
45DFHANDLER(backiconmgr)
46{
47	MoveIconManager(func);
48}
49
50/* XXX These two functions (Move/MoveMapped) really should be merged... */
51DFHANDLER(forwmapiconmgr)
52{
53	MoveMappedIconManager(func);
54}
55DFHANDLER(backmapiconmgr)
56{
57	MoveMappedIconManager(func);
58}
59
60/* Moving between icon managers */
61DFHANDLER(nexticonmgr)
62{
63	JumpIconManager(func);
64}
65DFHANDLER(previconmgr)
66{
67	JumpIconManager(func);
68}
69
70
71/*
72 * Showing/hiding the icon managers
73 */
74DFHANDLER(showiconmgr)
75{
76	IconMgr   *i;
77	WorkSpace *wl;
78
79	/*
80	 * XXX I don't think this is right; there can still be icon managers
81	 * to show even if we've never set any Workspaces {}.  And
82	 * HideIconManager() doesn't have this extra condition either...
83	 */
84	if(! Scr->workSpaceManagerActive) {
85		return;
86	}
87
88	if(Scr->NoIconManagers) {
89		return;
90	}
91
92	for(wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
93		for(i = wl->iconmgr; i != NULL; i = i->next) {
94			/* Don't show iconmgr's with nothing in 'em */
95			if(i->count == 0) {
96				continue;
97			}
98
99			/* If it oughta be in a vscreen, show it */
100			if(visible(i->twm_win)) {
101				/* IM window */
102				SetMapStateProp(i->twm_win, NormalState);
103				XMapWindow(dpy, i->twm_win->w);
104				OtpRaise(i->twm_win, WinWin);
105				XMapWindow(dpy, i->twm_win->frame);
106
107				/* Hide icon */
108				if(i->twm_win->icon && i->twm_win->icon->w) {
109					XUnmapWindow(dpy, i->twm_win->icon->w);
110				}
111			}
112
113			/* Mark as shown */
114			i->twm_win->mapped = true;
115			i->twm_win->isicon = false;
116		}
117	}
118}
119
120
121/*
122 * f.hideiconmanager is split into an external function (which is also
123 * exported) because it also gets called when f.delete{,ordestroy} is
124 * called on an icon manager.
125 *
126 * This hides all the icon managers in all the workspaces, and it doesn't
127 * leave icons behind, so it's _not_ the same as just iconifying, and
128 * thus not implemented by just calling Iconify(), but by doing the
129 * hiding manually.
130 */
131DFHANDLER(hideiconmgr)
132{
133	HideIconManager();
134}
135
136void
137HideIconManager(void)
138{
139	IconMgr   *i;
140	WorkSpace *wl;
141
142	if(Scr->NoIconManagers) {
143		return;
144	}
145
146	for(wl = Scr->workSpaceMgr.workSpaceList; wl != NULL; wl = wl->next) {
147		for(i = wl->iconmgr; i != NULL; i = i->next) {
148			/* Hide the IM window */
149			SetMapStateProp(i->twm_win, WithdrawnState);
150			XUnmapWindow(dpy, i->twm_win->frame);
151
152			/* Hide its icon */
153			if(i->twm_win->icon && i->twm_win->icon->w) {
154				XUnmapWindow(dpy, i->twm_win->icon->w);
155			}
156
157			/* Mark as pretend-iconified, even though the icon is hidden */
158			i->twm_win->mapped = false;
159			i->twm_win->isicon = true;
160		}
161	}
162}
163
164
165/*
166 * And sorting
167 */
168DFHANDLER(sorticonmgr)
169{
170	bool save_sort = Scr->SortIconMgr;
171
172	Scr->SortIconMgr = true;
173
174	if(context == C_ICONMGR) {
175		SortIconManager(NULL);
176	}
177	else if(tmp_win->isiconmgr) {
178		SortIconManager(tmp_win->iconmgrp);
179	}
180	else {
181		XBell(dpy, 0);
182	}
183
184	Scr->SortIconMgr = save_sort;
185}
186
187
188
189/*
190 * Now functions related to the workspace manager
191 */
192
193/*
194 * Showing/hiding it
195 */
196DFHANDLER(showworkspacemgr)
197{
198	if(! Scr->workSpaceManagerActive) {
199		return;
200	}
201
202	DeIconify(Scr->currentvs->wsw->twm_win);
203	OtpRaise(Scr->currentvs->wsw->twm_win, WinWin);
204}
205
206DFHANDLER(hideworkspacemgr)
207{
208	if(! Scr->workSpaceManagerActive) {
209		return;
210	}
211
212	Iconify(Scr->currentvs->wsw->twm_win, eventp->xbutton.x_root - 5,
213	        eventp->xbutton.y_root - 5);
214}
215
216DFHANDLER(toggleworkspacemgr)
217{
218	if(! Scr->workSpaceManagerActive) {
219		return;
220	}
221
222	if(Scr->currentvs->wsw->twm_win->mapped) {
223		Iconify(Scr->currentvs->wsw->twm_win, eventp->xbutton.x_root - 5,
224		        eventp->xbutton.y_root - 5);
225	}
226	else {
227		DeIconify(Scr->currentvs->wsw->twm_win);
228		OtpRaise(Scr->currentvs->wsw->twm_win, WinWin);
229	}
230}
231
232
233/*
234 * Flipping around map/button state
235 */
236DFHANDLER(togglestate)
237{
238	WMgrToggleState(Scr->currentvs);
239}
240
241DFHANDLER(setbuttonsstate)
242{
243	WMgrSetButtonsState(Scr->currentvs);
244}
245
246DFHANDLER(setmapstate)
247{
248	WMgrSetMapState(Scr->currentvs);
249}
250