Mac OS X-style window cycling.
[wmaker-crm.git] / WPrefs.app / KeyboardShortcuts.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/* KeyboardShortcuts.c- keyboard shortcut bindings
6830b057 dan2004-10-12 21:28:27 +00002 *
9af1c6c4 dan1998-10-21 14:43:47 +00003 * WPrefs - Window Maker Preferences Program
6830b057 dan2004-10-12 21:28:27 +00004 *
4153e2fd dan2003-01-16 23:30:45 +00005 * Copyright (c) 1998-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00006 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00007 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
6830b057 dan2004-10-12 21:28:27 +000019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
9d2e6ef9 scottc1998-09-29 22:36:29 +000020 * USA.
21 */
22
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020023#include "config.h" /* for HAVE_XCONVERTCASE */
5db8b566 kojima2002-02-15 21:34:46 +000024
9d2e6ef9 scottc1998-09-29 22:36:29 +000025#include "WPrefs.h"
26#include <ctype.h>
27
28#include <X11/keysym.h>
29
9d2e6ef9 scottc1998-09-29 22:36:29 +000030typedef struct _Panel {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020031 WMBox *box;
9d2e6ef9 scottc1998-09-29 22:36:29 +000032
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020033 char *sectionName;
d3f29988 kojima1999-04-25 01:49:46 +000034
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020035 char *description;
d3f29988 kojima1999-04-25 01:49:46 +000036
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020037 CallbackRec callbacks;
9d2e6ef9 scottc1998-09-29 22:36:29 +000038
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020039 WMWidget *parent;
9d2e6ef9 scottc1998-09-29 22:36:29 +000040
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020041 WMLabel *actL;
42 WMList *actLs;
6830b057 dan2004-10-12 21:28:27 +000043
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020044 WMFrame *shoF;
45 WMTextField *shoT;
46 WMButton *cleB;
47 WMButton *defB;
9d2e6ef9 scottc1998-09-29 22:36:29 +000048
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020049 WMLabel *instructionsL;
0261c326 dan1999-01-06 15:22:33 +000050
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020051 WMColor *white;
52 WMColor *black;
53 WMColor *gray;
54 WMFont *font;
0261c326 dan1999-01-06 15:22:33 +000055
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020056 /**/ char capturing;
57 char **shortcuts;
58 int actionCount;
9d2e6ef9 scottc1998-09-29 22:36:29 +000059} _Panel;
60
9d2e6ef9 scottc1998-09-29 22:36:29 +000061#define ICON_FILE "keyshortcuts"
62
9d2e6ef9 scottc1998-09-29 22:36:29 +000063/* must be in the same order as the corresponding items in actions list */
64static char *keyOptions[] = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020065 "RootMenuKey",
66 "WindowListKey",
67 "WindowMenuKey",
68 "HideKey",
69 "HideOthersKey",
70 "MiniaturizeKey",
71 "CloseKey",
72 "MaximizeKey",
73 "VMaximizeKey",
74 "HMaximizeKey",
69244548
JH
Johann Haarhoff2009-08-28 21:31:26 +020075 "LHMaximizeKey",
76 "RHMaximizeKey",
9789cf31 Carlos R. Mafra2009-09-14 16:34:37 +020077 "MaximusKey",
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020078 "RaiseKey",
79 "LowerKey",
80 "RaiseLowerKey",
81 "ShadeKey",
82 "MoveResizeKey",
83 "SelectKey",
84 "FocusNextKey",
85 "FocusPrevKey",
18408fff
IP
Iain Patterson2009-09-14 14:37:15 +010086 "GroupNextKey",
87 "GroupPrevKey",
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020088 "NextWorkspaceKey",
89 "PrevWorkspaceKey",
90 "NextWorkspaceLayerKey",
91 "PrevWorkspaceLayerKey",
92 "Workspace1Key",
93 "Workspace2Key",
94 "Workspace3Key",
95 "Workspace4Key",
96 "Workspace5Key",
97 "Workspace6Key",
98 "Workspace7Key",
99 "Workspace8Key",
100 "Workspace9Key",
101 "Workspace10Key",
102 "WindowShortcut1Key",
103 "WindowShortcut2Key",
104 "WindowShortcut3Key",
105 "WindowShortcut4Key",
106 "WindowShortcut5Key",
107 "WindowShortcut6Key",
108 "WindowShortcut7Key",
109 "WindowShortcut8Key",
110 "WindowShortcut9Key",
111 "WindowShortcut10Key",
112 "ScreenSwitchKey",
9aca0d5f dan2004-10-12 01:34:32 +0000113#ifdef VIRTUAL_DESKTOP
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200114 "VirtualEdgeLeftKey",
115 "VirtualEdgeRightKey",
116 "VirtualEdgeUpKey",
117 "VirtualEdgeDownKey",
9aca0d5f dan2004-10-12 01:34:32 +0000118#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200119 "ClipRaiseKey",
120 "ClipLowerKey",
59eb9475 dan1998-11-03 12:53:26 +0000121#ifndef XKB_MODELOCK
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200122 "ClipRaiseLowerKey"
59eb9475 dan1998-11-03 12:53:26 +0000123#else
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200124 "ClipRaiseLowerKey",
125 "ToggleKbdModeKey"
126#endif /* XKB_MODELOCK */
9d2e6ef9 scottc1998-09-29 22:36:29 +0000127};
128
5db8b566 kojima2002-02-15 21:34:46 +0000129#ifndef HAVE_XCONVERTCASE
130/* from Xlib */
131
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200132static void XConvertCase(register KeySym sym, KeySym * lower, KeySym * upper)
5db8b566 kojima2002-02-15 21:34:46 +0000133{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200134 *lower = sym;
135 *upper = sym;
136 switch (sym >> 8) {
137 case 0: /* Latin 1 */
138 if ((sym >= XK_A) && (sym <= XK_Z))
139 *lower += (XK_a - XK_A);
140 else if ((sym >= XK_a) && (sym <= XK_z))
141 *upper -= (XK_a - XK_A);
142 else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
143 *lower += (XK_agrave - XK_Agrave);
144 else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
145 *upper -= (XK_agrave - XK_Agrave);
146 else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
147 *lower += (XK_oslash - XK_Ooblique);
148 else if ((sym >= XK_oslash) && (sym <= XK_thorn))
149 *upper -= (XK_oslash - XK_Ooblique);
150 break;
151 case 1: /* Latin 2 */
152 /* Assume the KeySym is a legal value (ignore discontinuities) */
153 if (sym == XK_Aogonek)
154 *lower = XK_aogonek;
155 else if (sym >= XK_Lstroke && sym <= XK_Sacute)
156 *lower += (XK_lstroke - XK_Lstroke);
157 else if (sym >= XK_Scaron && sym <= XK_Zacute)
158 *lower += (XK_scaron - XK_Scaron);
159 else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
160 *lower += (XK_zcaron - XK_Zcaron);
161 else if (sym == XK_aogonek)
162 *upper = XK_Aogonek;
163 else if (sym >= XK_lstroke && sym <= XK_sacute)
164 *upper -= (XK_lstroke - XK_Lstroke);
165 else if (sym >= XK_scaron && sym <= XK_zacute)
166 *upper -= (XK_scaron - XK_Scaron);
167 else if (sym >= XK_zcaron && sym <= XK_zabovedot)
168 *upper -= (XK_zcaron - XK_Zcaron);
169 else if (sym >= XK_Racute && sym <= XK_Tcedilla)
170 *lower += (XK_racute - XK_Racute);
171 else if (sym >= XK_racute && sym <= XK_tcedilla)
172 *upper -= (XK_racute - XK_Racute);
173 break;
174 case 2: /* Latin 3 */
175 /* Assume the KeySym is a legal value (ignore discontinuities) */
176 if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
177 *lower += (XK_hstroke - XK_Hstroke);
178 else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
179 *lower += (XK_gbreve - XK_Gbreve);
180 else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
181 *upper -= (XK_hstroke - XK_Hstroke);
182 else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
183 *upper -= (XK_gbreve - XK_Gbreve);
184 else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
185 *lower += (XK_cabovedot - XK_Cabovedot);
186 else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
187 *upper -= (XK_cabovedot - XK_Cabovedot);
188 break;
189 case 3: /* Latin 4 */
190 /* Assume the KeySym is a legal value (ignore discontinuities) */
191 if (sym >= XK_Rcedilla && sym <= XK_Tslash)
192 *lower += (XK_rcedilla - XK_Rcedilla);
193 else if (sym >= XK_rcedilla && sym <= XK_tslash)
194 *upper -= (XK_rcedilla - XK_Rcedilla);
195 else if (sym == XK_ENG)
196 *lower = XK_eng;
197 else if (sym == XK_eng)
198 *upper = XK_ENG;
199 else if (sym >= XK_Amacron && sym <= XK_Umacron)
200 *lower += (XK_amacron - XK_Amacron);
201 else if (sym >= XK_amacron && sym <= XK_umacron)
202 *upper -= (XK_amacron - XK_Amacron);
203 break;
204 case 6: /* Cyrillic */
205 /* Assume the KeySym is a legal value (ignore discontinuities) */
206 if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
207 *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
208 else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
209 *upper += (XK_Serbian_DJE - XK_Serbian_dje);
210 else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
211 *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
212 else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
213 *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
214 break;
215 case 7: /* Greek */
216 /* Assume the KeySym is a legal value (ignore discontinuities) */
217 if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
218 *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
219 else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
220 sym != XK_Greek_iotaaccentdieresis && sym != XK_Greek_upsilonaccentdieresis)
221 *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
222 else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
223 *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
224 else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && sym != XK_Greek_finalsmallsigma)
225 *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
226 break;
227 case 0x14: /* Armenian */
228 if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) {
229 *lower = sym | 1;
230 *upper = sym & ~1;
231 }
232 break;
233 }
5db8b566 kojima2002-02-15 21:34:46 +0000234}
235#endif
236
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200237static char *captureShortcut(Display * dpy, _Panel * panel)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000238{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200239 XEvent ev;
240 KeySym ksym, lksym, uksym;
241 char buffer[64];
242 char *key = NULL;
243
244 while (panel->capturing) {
245 XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
246 WMNextEvent(dpy, &ev);
247 if (ev.type == KeyPress && ev.xkey.keycode != 0) {
248 ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
249 if (!IsModifierKey(ksym)) {
250 XConvertCase(ksym, &lksym, &uksym);
251 key = XKeysymToString(uksym);
252
253 panel->capturing = 0;
254 break;
255 }
256 }
257 WMHandleEvent(&ev);
258 }
259
260 if (!key)
261 return NULL;
262
263 buffer[0] = 0;
264
265 if (ev.xkey.state & ControlMask) {
266 strcat(buffer, "Control+");
267 }
268 if (ev.xkey.state & ShiftMask) {
269 strcat(buffer, "Shift+");
270 }
271 if (ev.xkey.state & Mod1Mask) {
272 strcat(buffer, "Mod1+");
273 }
274 if (ev.xkey.state & Mod2Mask) {
275 strcat(buffer, "Mod2+");
276 }
277 if (ev.xkey.state & Mod3Mask) {
278 strcat(buffer, "Mod3+");
279 }
280 if (ev.xkey.state & Mod4Mask) {
281 strcat(buffer, "Mod4+");
282 }
283 if (ev.xkey.state & Mod5Mask) {
284 strcat(buffer, "Mod5+");
285 }
286 strcat(buffer, key);
287
288 return wstrdup(buffer);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000289}
290
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200291static void captureClick(WMWidget * w, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000292{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200293 _Panel *panel = (_Panel *) data;
294 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
295 char *shortcut;
296
297 if (!panel->capturing) {
298 panel->capturing = 1;
299 WMSetButtonText(w, _("Cancel"));
300 WMSetLabelText(panel->instructionsL,
301 _("Press the desired shortcut key(s) or click Cancel to stop capturing."));
302 XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync, GrabModeAsync, CurrentTime);
303 shortcut = captureShortcut(dpy, panel);
304 if (shortcut) {
305 int row = WMGetListSelectedItemRow(panel->actLs);
306
307 WMSetTextFieldText(panel->shoT, shortcut);
308 if (row >= 0) {
309 if (panel->shortcuts[row])
310 wfree(panel->shortcuts[row]);
311 panel->shortcuts[row] = shortcut;
312
313 WMRedisplayWidget(panel->actLs);
314 } else {
315 wfree(shortcut);
316 }
317 }
318 }
319 panel->capturing = 0;
320 WMSetButtonText(w, _("Capture"));
321 WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
322 XUngrabKeyboard(dpy, CurrentTime);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000323}
324
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200325static void clearShortcut(WMWidget * w, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000326{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200327 _Panel *panel = (_Panel *) data;
328 int row = WMGetListSelectedItemRow(panel->actLs);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000329
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200330 WMSetTextFieldText(panel->shoT, NULL);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000331
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200332 if (row >= 0) {
333 if (panel->shortcuts[row])
334 wfree(panel->shortcuts[row]);
335 panel->shortcuts[row] = NULL;
336 WMRedisplayWidget(panel->actLs);
337 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000338}
339
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200340static void typedKeys(void *observerData, WMNotification * notification)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000341{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200342 _Panel *panel = (_Panel *) observerData;
343 int row = WMGetListSelectedItemRow(panel->actLs);
344
345 if (row < 0)
346 return;
347
348 if (panel->shortcuts[row])
349 wfree(panel->shortcuts[row]);
350 panel->shortcuts[row] = WMGetTextFieldText(panel->shoT);
351 if (strlen(panel->shortcuts[row]) == 0) {
352 wfree(panel->shortcuts[row]);
353 panel->shortcuts[row] = NULL;
354 }
355 WMRedisplayWidget(panel->actLs);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000356}
357
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200358static void listClick(WMWidget * w, void *data)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000359{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200360 _Panel *panel = (_Panel *) data;
361 int row = WMGetListSelectedItemRow(w);
6830b057 dan2004-10-12 21:28:27 +0000362
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200363 WMSetTextFieldText(panel->shoT, panel->shortcuts[row]);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000364}
365
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200366static char *trimstr(char *str)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000367{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200368 char *p = str;
369 int i;
370
371 while (isspace(*p))
372 p++;
373 p = wstrdup(p);
374 i = strlen(p);
375 while (isspace(p[i]) && i > 0) {
376 p[i] = 0;
377 i--;
378 }
379
380 return p;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000381}
382
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200383static void showData(_Panel * panel)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000384{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200385 char *str;
386 int i;
387
388 for (i = 0; i < panel->actionCount; i++) {
389
390 str = GetStringForKey(keyOptions[i]);
391 if (panel->shortcuts[i])
392 wfree(panel->shortcuts[i]);
393 if (str)
394 panel->shortcuts[i] = trimstr(str);
395 else
396 panel->shortcuts[i] = NULL;
397
398 if (panel->shortcuts[i] &&
399 (strcasecmp(panel->shortcuts[i], "none") == 0 || strlen(panel->shortcuts[i]) == 0)) {
400 wfree(panel->shortcuts[i]);
401 panel->shortcuts[i] = NULL;
402 }
403 }
404 WMRedisplayWidget(panel->actLs);
0261c326 dan1999-01-06 15:22:33 +0000405}
406
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200407static void paintItem(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
0261c326 dan1999-01-06 15:22:33 +0000408{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200409 int width, height, x, y;
410 _Panel *panel = (_Panel *) WMGetHangedData(lPtr);
411 WMScreen *scr = WMWidgetScreen(lPtr);
412 Display *dpy = WMScreenDisplay(scr);
413 WMColor *backColor = (state & WLDSSelected) ? panel->white : panel->gray;
0261c326 dan1999-01-06 15:22:33 +0000414
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200415 width = rect->size.width;
416 height = rect->size.height;
417 x = rect->pos.x;
418 y = rect->pos.y;
0261c326 dan1999-01-06 15:22:33 +0000419
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200420 XFillRectangle(dpy, d, WMColorGC(backColor), x, y, width, height);
0261c326 dan1999-01-06 15:22:33 +0000421
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200422 if (panel->shortcuts[index]) {
423 WMPixmap *pix = WMGetSystemPixmap(scr, WSICheckMark);
424 WMSize size = WMGetPixmapSize(pix);
6830b057 dan2004-10-12 21:28:27 +0000425
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200426 WMDrawPixmap(pix, d, x + (20 - size.width) / 2, (height - size.height) / 2 + y);
427 WMReleasePixmap(pix);
428 }
0261c326 dan1999-01-06 15:22:33 +0000429
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200430 WMDrawString(scr, d, panel->black, panel->font, x + 20, y, text, strlen(text));
9d2e6ef9 scottc1998-09-29 22:36:29 +0000431}
432
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200433static void createPanel(Panel * p)
6830b057 dan2004-10-12 21:28:27 +0000434{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200435 _Panel *panel = (_Panel *) p;
436 WMScreen *scr = WMWidgetScreen(panel->parent);
437 WMColor *color;
438 WMFont *boldFont;
439
440 panel->capturing = 0;
441
442 panel->white = WMWhiteColor(scr);
443 panel->black = WMBlackColor(scr);
444 panel->gray = WMGrayColor(scr);
445 panel->font = WMSystemFontOfSize(scr, 12);
446
447 panel->box = WMCreateBox(panel->parent);
448 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
449
450 boldFont = WMBoldSystemFontOfSize(scr, 12);
451
452 /* **************** Actions **************** */
453 panel->actL = WMCreateLabel(panel->box);
454 WMResizeWidget(panel->actL, 280, 20);
455 WMMoveWidget(panel->actL, 20, 10);
456 WMSetLabelFont(panel->actL, boldFont);
457 WMSetLabelText(panel->actL, _("Actions"));
458 WMSetLabelRelief(panel->actL, WRSunken);
459 WMSetLabelTextAlignment(panel->actL, WACenter);
460 color = WMDarkGrayColor(scr);
461 WMSetWidgetBackgroundColor(panel->actL, color);
462 WMReleaseColor(color);
463 WMSetLabelTextColor(panel->actL, panel->white);
464
465 panel->actLs = WMCreateList(panel->box);
466 WMResizeWidget(panel->actLs, 280, 190);
467 WMMoveWidget(panel->actLs, 20, 32);
468 WMSetListUserDrawProc(panel->actLs, paintItem);
469 WMHangData(panel->actLs, panel);
470
471 WMAddListItem(panel->actLs, _("Open applications menu"));
472 WMAddListItem(panel->actLs, _("Open window list menu"));
473 WMAddListItem(panel->actLs, _("Open window commands menu"));
474 WMAddListItem(panel->actLs, _("Hide active application"));
475 WMAddListItem(panel->actLs, _("Hide other applications"));
476 WMAddListItem(panel->actLs, _("Miniaturize active window"));
477 WMAddListItem(panel->actLs, _("Close active window"));
478 WMAddListItem(panel->actLs, _("Maximize active window"));
479 WMAddListItem(panel->actLs, _("Maximize active window vertically"));
480 WMAddListItem(panel->actLs, _("Maximize active window horizontally"));
69244548
JH
Johann Haarhoff2009-08-28 21:31:26 +0200481 WMAddListItem(panel->actLs, _("Maximize active window left half"));
482 WMAddListItem(panel->actLs, _("Maximize active window right half"));
9789cf31 Carlos R. Mafra2009-09-14 16:34:37 +0200483 WMAddListItem(panel->actLs, _("Maximus: Tiled maximization "));
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200484 WMAddListItem(panel->actLs, _("Raise active window"));
485 WMAddListItem(panel->actLs, _("Lower active window"));
486 WMAddListItem(panel->actLs, _("Raise/Lower window under mouse pointer"));
487 WMAddListItem(panel->actLs, _("Shade active window"));
488 WMAddListItem(panel->actLs, _("Move/Resize active window"));
489 WMAddListItem(panel->actLs, _("Select active window"));
490 WMAddListItem(panel->actLs, _("Focus next window"));
491 WMAddListItem(panel->actLs, _("Focus previous window"));
18408fff
IP
Iain Patterson2009-09-14 14:37:15 +0100492 WMAddListItem(panel->actLs, _("Focus next group window"));
493 WMAddListItem(panel->actLs, _("Focus previous group window"));
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200494 WMAddListItem(panel->actLs, _("Switch to next workspace"));
495 WMAddListItem(panel->actLs, _("Switch to previous workspace"));
496 WMAddListItem(panel->actLs, _("Switch to next ten workspaces"));
497 WMAddListItem(panel->actLs, _("Switch to previous ten workspaces"));
498 WMAddListItem(panel->actLs, _("Switch to workspace 1"));
499 WMAddListItem(panel->actLs, _("Switch to workspace 2"));
500 WMAddListItem(panel->actLs, _("Switch to workspace 3"));
501 WMAddListItem(panel->actLs, _("Switch to workspace 4"));
502 WMAddListItem(panel->actLs, _("Switch to workspace 5"));
503 WMAddListItem(panel->actLs, _("Switch to workspace 6"));
504 WMAddListItem(panel->actLs, _("Switch to workspace 7"));
505 WMAddListItem(panel->actLs, _("Switch to workspace 8"));
506 WMAddListItem(panel->actLs, _("Switch to workspace 9"));
507 WMAddListItem(panel->actLs, _("Switch to workspace 10"));
508 WMAddListItem(panel->actLs, _("Shortcut for window 1"));
509 WMAddListItem(panel->actLs, _("Shortcut for window 2"));
510 WMAddListItem(panel->actLs, _("Shortcut for window 3"));
511 WMAddListItem(panel->actLs, _("Shortcut for window 4"));
512 WMAddListItem(panel->actLs, _("Shortcut for window 5"));
513 WMAddListItem(panel->actLs, _("Shortcut for window 6"));
514 WMAddListItem(panel->actLs, _("Shortcut for window 7"));
515 WMAddListItem(panel->actLs, _("Shortcut for window 8"));
516 WMAddListItem(panel->actLs, _("Shortcut for window 9"));
517 WMAddListItem(panel->actLs, _("Shortcut for window 10"));
518 WMAddListItem(panel->actLs, _("Switch to Next Screen/Monitor"));
9aca0d5f dan2004-10-12 01:34:32 +0000519#ifdef VIRTUAL_DESKTOP
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200520 WMAddListItem(panel->actLs, _("Move VirtualDesktop to next left edge"));
521 WMAddListItem(panel->actLs, _("Move VirtualDesktop to next right edge"));
522 WMAddListItem(panel->actLs, _("Move VirtualDesktop to next top edge"));
523 WMAddListItem(panel->actLs, _("Move VirtualDesktop to next bottom edge"));
9aca0d5f dan2004-10-12 01:34:32 +0000524#endif
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200525 WMAddListItem(panel->actLs, _("Raise Clip"));
526 WMAddListItem(panel->actLs, _("Lower Clip"));
527 WMAddListItem(panel->actLs, _("Raise/Lower Clip"));
59eb9475 dan1998-11-03 12:53:26 +0000528#ifdef XKB_MODELOCK
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200529 WMAddListItem(panel->actLs, _("Toggle keyboard language"));
530#endif /* XKB_MODELOCK */
9d2e6ef9 scottc1998-09-29 22:36:29 +0000531
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200532 WMSetListAction(panel->actLs, listClick, panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000533
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200534 panel->actionCount = WMGetListNumberOfRows(panel->actLs);
535 panel->shortcuts = wmalloc(sizeof(char *) * panel->actionCount);
536 memset(panel->shortcuts, 0, sizeof(char *) * panel->actionCount);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000537
538 /***************** Shortcut ****************/
539
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200540 panel->shoF = WMCreateFrame(panel->box);
541 WMResizeWidget(panel->shoF, 190, 210);
542 WMMoveWidget(panel->shoF, 315, 10);
543 WMSetFrameTitle(panel->shoF, _("Shortcut"));
6830b057 dan2004-10-12 21:28:27 +0000544
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200545 panel->shoT = WMCreateTextField(panel->shoF);
546 WMResizeWidget(panel->shoT, 160, 20);
547 WMMoveWidget(panel->shoT, 15, 65);
548 WMAddNotificationObserver(typedKeys, panel, WMTextDidChangeNotification, panel->shoT);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000549
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200550 panel->cleB = WMCreateCommandButton(panel->shoF);
551 WMResizeWidget(panel->cleB, 75, 24);
552 WMMoveWidget(panel->cleB, 15, 95);
553 WMSetButtonText(panel->cleB, _("Clear"));
554 WMSetButtonAction(panel->cleB, clearShortcut, panel);
6830b057 dan2004-10-12 21:28:27 +0000555
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200556 panel->defB = WMCreateCommandButton(panel->shoF);
557 WMResizeWidget(panel->defB, 75, 24);
558 WMMoveWidget(panel->defB, 100, 95);
559 WMSetButtonText(panel->defB, _("Capture"));
560 WMSetButtonAction(panel->defB, captureClick, panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000561
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200562 panel->instructionsL = WMCreateLabel(panel->shoF);
563 WMResizeWidget(panel->instructionsL, 160, 55);
564 WMMoveWidget(panel->instructionsL, 15, 140);
565 WMSetLabelTextAlignment(panel->instructionsL, WACenter);
566 WMSetLabelWraps(panel->instructionsL, True);
567 WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
6830b057 dan2004-10-12 21:28:27 +0000568
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200569 WMMapSubwidgets(panel->shoF);
6830b057 dan2004-10-12 21:28:27 +0000570
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200571 WMReleaseFont(boldFont);
6830b057 dan2004-10-12 21:28:27 +0000572
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200573 WMRealizeWidget(panel->box);
574 WMMapSubwidgets(panel->box);
6830b057 dan2004-10-12 21:28:27 +0000575
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200576 showData(panel);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000577}
578
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200579static void storeData(_Panel * panel)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000580{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200581 int i;
582 char *str;
583
584 for (i = 0; i < panel->actionCount; i++) {
585 str = NULL;
586 if (panel->shortcuts[i]) {
587 str = trimstr(panel->shortcuts[i]);
588 if (strlen(str) == 0) {
589 wfree(str);
590 str = NULL;
591 }
592 }
593 if (str) {
594 SetStringForKey(str, keyOptions[i]);
595 wfree(str);
596 } else {
597 SetStringForKey("None", keyOptions[i]);
598 }
599 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000600}
601
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200602Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000603{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200604 _Panel *panel;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000605
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200606 panel = wmalloc(sizeof(_Panel));
607 memset(panel, 0, sizeof(_Panel));
9d2e6ef9 scottc1998-09-29 22:36:29 +0000608
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200609 panel->sectionName = _("Keyboard Shortcut Preferences");
9d2e6ef9 scottc1998-09-29 22:36:29 +0000610
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200611 panel->description = _("Change the keyboard shortcuts for actions such\n"
612 "as changing workspaces and opening menus.");
d3f29988 kojima1999-04-25 01:49:46 +0000613
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200614 panel->parent = parent;
1e922744 dan2002-10-16 04:05:45 +0000615
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200616 panel->callbacks.createWidgets = createPanel;
617 panel->callbacks.updateDomain = storeData;
0261c326 dan1999-01-06 15:22:33 +0000618
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200619 AddSection(panel, ICON_FILE);
1e922744 dan2002-10-16 04:05:45 +0000620
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200621 return panel;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000622}