Allow WPrefs to configure workspace switching keys.
[wmaker-crm.git] / WPrefs.app / KeyboardShortcuts.c
blob61a49a1a1a4032fccbe95270006139b75c03ca02
1 /* KeyboardShortcuts.c- keyboard shortcut bindings
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 1998-2003 Alfredo K. Kojima
7 * 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.
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.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "config.h" /* for HAVE_XCONVERTCASE */
24 #include "WPrefs.h"
25 #include <ctype.h>
27 #include <X11/keysym.h>
28 #include <X11/XKBlib.h>
30 typedef struct _Panel {
31 WMBox *box;
33 char *sectionName;
35 char *description;
37 CallbackRec callbacks;
39 WMWidget *parent;
41 WMLabel *actL;
42 WMList *actLs;
44 WMFrame *shoF;
45 WMTextField *shoT;
46 WMButton *cleB;
47 WMButton *defB;
49 WMLabel *instructionsL;
51 WMColor *white;
52 WMColor *black;
53 WMColor *gray;
54 WMFont *font;
56 Bool capturing;
57 char **shortcuts;
58 int actionCount;
59 } _Panel;
61 #define ICON_FILE "keyshortcuts"
64 * Must be in the same order as the corresponding items in
65 * "actions list" in createPanel()
67 static char *keyOptions[] = {
68 "RootMenuKey",
69 "WindowListKey",
70 "WindowMenuKey",
71 "HideKey",
72 "HideOthersKey",
73 "MiniaturizeKey",
74 "MinimizeAllKey",
75 "CloseKey",
76 "MaximizeKey",
77 "VMaximizeKey",
78 "HMaximizeKey",
79 "LHMaximizeKey",
80 "RHMaximizeKey",
81 "MaximusKey",
82 "RaiseKey",
83 "LowerKey",
84 "RaiseLowerKey",
85 "ShadeKey",
86 "MoveResizeKey",
87 "SelectKey",
88 "FocusNextKey",
89 "FocusPrevKey",
90 "GroupNextKey",
91 "GroupPrevKey",
92 "NextWorkspaceKey",
93 "PrevWorkspaceKey",
94 "LastWorkspaceKey",
95 "NextWorkspaceLayerKey",
96 "PrevWorkspaceLayerKey",
97 "Workspace1Key",
98 "Workspace2Key",
99 "Workspace3Key",
100 "Workspace4Key",
101 "Workspace5Key",
102 "Workspace6Key",
103 "Workspace7Key",
104 "Workspace8Key",
105 "Workspace9Key",
106 "Workspace10Key",
107 "MoveToNextWorkspaceKey",
108 "MoveToPrevWorkspaceKey",
109 "MoveToLastWorkspaceKey",
110 "MoveToNextWorkspaceLayerKey",
111 "MoveToPrevWorkspaceLayerKey",
112 "MoveToWorkspace1Key",
113 "MoveToWorkspace2Key",
114 "MoveToWorkspace3Key",
115 "MoveToWorkspace4Key",
116 "MoveToWorkspace5Key",
117 "MoveToWorkspace6Key",
118 "MoveToWorkspace7Key",
119 "MoveToWorkspace8Key",
120 "MoveToWorkspace9Key",
121 "MoveToWorkspace10Key",
122 "WindowShortcut1Key",
123 "WindowShortcut2Key",
124 "WindowShortcut3Key",
125 "WindowShortcut4Key",
126 "WindowShortcut5Key",
127 "WindowShortcut6Key",
128 "WindowShortcut7Key",
129 "WindowShortcut8Key",
130 "WindowShortcut9Key",
131 "WindowShortcut10Key",
132 "WindowRelaunchKey",
133 "ScreenSwitchKey",
134 "DockRaiseLowerKey",
135 #ifndef XKB_MODELOCK
136 "ClipRaiseLowerKey"
137 #else
138 "ClipRaiseLowerKey",
139 "ToggleKbdModeKey"
140 #endif /* XKB_MODELOCK */
143 #ifndef HAVE_XCONVERTCASE
144 /* from Xlib */
146 static void XConvertCase(register KeySym sym, KeySym * lower, KeySym * upper)
148 *lower = sym;
149 *upper = sym;
150 switch (sym >> 8) {
151 case 0: /* Latin 1 */
152 if ((sym >= XK_A) && (sym <= XK_Z))
153 *lower += (XK_a - XK_A);
154 else if ((sym >= XK_a) && (sym <= XK_z))
155 *upper -= (XK_a - XK_A);
156 else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
157 *lower += (XK_agrave - XK_Agrave);
158 else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
159 *upper -= (XK_agrave - XK_Agrave);
160 else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
161 *lower += (XK_oslash - XK_Ooblique);
162 else if ((sym >= XK_oslash) && (sym <= XK_thorn))
163 *upper -= (XK_oslash - XK_Ooblique);
164 break;
165 case 1: /* Latin 2 */
166 /* Assume the KeySym is a legal value (ignore discontinuities) */
167 if (sym == XK_Aogonek)
168 *lower = XK_aogonek;
169 else if (sym >= XK_Lstroke && sym <= XK_Sacute)
170 *lower += (XK_lstroke - XK_Lstroke);
171 else if (sym >= XK_Scaron && sym <= XK_Zacute)
172 *lower += (XK_scaron - XK_Scaron);
173 else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
174 *lower += (XK_zcaron - XK_Zcaron);
175 else if (sym == XK_aogonek)
176 *upper = XK_Aogonek;
177 else if (sym >= XK_lstroke && sym <= XK_sacute)
178 *upper -= (XK_lstroke - XK_Lstroke);
179 else if (sym >= XK_scaron && sym <= XK_zacute)
180 *upper -= (XK_scaron - XK_Scaron);
181 else if (sym >= XK_zcaron && sym <= XK_zabovedot)
182 *upper -= (XK_zcaron - XK_Zcaron);
183 else if (sym >= XK_Racute && sym <= XK_Tcedilla)
184 *lower += (XK_racute - XK_Racute);
185 else if (sym >= XK_racute && sym <= XK_tcedilla)
186 *upper -= (XK_racute - XK_Racute);
187 break;
188 case 2: /* Latin 3 */
189 /* Assume the KeySym is a legal value (ignore discontinuities) */
190 if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
191 *lower += (XK_hstroke - XK_Hstroke);
192 else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
193 *lower += (XK_gbreve - XK_Gbreve);
194 else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
195 *upper -= (XK_hstroke - XK_Hstroke);
196 else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
197 *upper -= (XK_gbreve - XK_Gbreve);
198 else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
199 *lower += (XK_cabovedot - XK_Cabovedot);
200 else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
201 *upper -= (XK_cabovedot - XK_Cabovedot);
202 break;
203 case 3: /* Latin 4 */
204 /* Assume the KeySym is a legal value (ignore discontinuities) */
205 if (sym >= XK_Rcedilla && sym <= XK_Tslash)
206 *lower += (XK_rcedilla - XK_Rcedilla);
207 else if (sym >= XK_rcedilla && sym <= XK_tslash)
208 *upper -= (XK_rcedilla - XK_Rcedilla);
209 else if (sym == XK_ENG)
210 *lower = XK_eng;
211 else if (sym == XK_eng)
212 *upper = XK_ENG;
213 else if (sym >= XK_Amacron && sym <= XK_Umacron)
214 *lower += (XK_amacron - XK_Amacron);
215 else if (sym >= XK_amacron && sym <= XK_umacron)
216 *upper -= (XK_amacron - XK_Amacron);
217 break;
218 case 6: /* Cyrillic */
219 /* Assume the KeySym is a legal value (ignore discontinuities) */
220 if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
221 *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
222 else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
223 *upper += (XK_Serbian_DJE - XK_Serbian_dje);
224 else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
225 *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
226 else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
227 *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
228 break;
229 case 7: /* Greek */
230 /* Assume the KeySym is a legal value (ignore discontinuities) */
231 if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
232 *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
233 else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
234 sym != XK_Greek_iotaaccentdieresis && sym != XK_Greek_upsilonaccentdieresis)
235 *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
236 else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
237 *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
238 else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && sym != XK_Greek_finalsmallsigma)
239 *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
240 break;
241 case 0x14: /* Armenian */
242 if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) {
243 *lower = sym | 1;
244 *upper = sym & ~1;
246 break;
249 #endif
251 char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case)
253 XEvent ev;
254 KeySym ksym, lksym, uksym;
255 char buffer[64];
256 char *key = NULL;
258 while (*capturing) {
259 XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
260 WMNextEvent(dpy, &ev);
261 if (ev.type == KeyPress && ev.xkey.keycode != 0) {
262 ksym = XkbKeycodeToKeysym(dpy, ev.xkey.keycode, 0, 0);
263 if (!IsModifierKey(ksym)) {
264 if (convert_case) {
265 XConvertCase(ksym, &lksym, &uksym);
266 key = XKeysymToString(uksym);
267 } else {
268 key = XKeysymToString(ksym);
271 *capturing = 0;
272 break;
275 WMHandleEvent(&ev);
278 if (!key)
279 return NULL;
281 buffer[0] = 0;
283 if (ev.xkey.state & ControlMask) {
284 strcat(buffer, "Control+");
286 if (ev.xkey.state & ShiftMask) {
287 strcat(buffer, "Shift+");
289 if (ev.xkey.state & Mod1Mask) {
290 strcat(buffer, "Mod1+");
292 if (ev.xkey.state & Mod2Mask) {
293 strcat(buffer, "Mod2+");
295 if (ev.xkey.state & Mod3Mask) {
296 strcat(buffer, "Mod3+");
298 if (ev.xkey.state & Mod4Mask) {
299 strcat(buffer, "Mod4+");
301 if (ev.xkey.state & Mod5Mask) {
302 strcat(buffer, "Mod5+");
304 strcat(buffer, key);
306 return wstrdup(buffer);
309 static void captureClick(WMWidget * w, void *data)
311 _Panel *panel = (_Panel *) data;
312 Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
313 char *shortcut;
315 if (!panel->capturing) {
316 panel->capturing = 1;
317 WMSetButtonText(w, _("Cancel"));
318 WMSetLabelText(panel->instructionsL,
319 _("Press the desired shortcut key(s) or click Cancel to stop capturing."));
320 XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync, GrabModeAsync, CurrentTime);
321 shortcut = capture_shortcut(dpy, &panel->capturing, 1);
322 if (shortcut) {
323 int row = WMGetListSelectedItemRow(panel->actLs);
325 WMSetTextFieldText(panel->shoT, shortcut);
326 if (row >= 0) {
327 if (panel->shortcuts[row])
328 wfree(panel->shortcuts[row]);
329 panel->shortcuts[row] = shortcut;
331 WMRedisplayWidget(panel->actLs);
332 } else {
333 wfree(shortcut);
337 panel->capturing = 0;
338 WMSetButtonText(w, _("Capture"));
339 WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
340 XUngrabKeyboard(dpy, CurrentTime);
343 static void clearShortcut(WMWidget * w, void *data)
345 _Panel *panel = (_Panel *) data;
346 int row = WMGetListSelectedItemRow(panel->actLs);
348 WMSetTextFieldText(panel->shoT, NULL);
350 if (row >= 0) {
351 if (panel->shortcuts[row])
352 wfree(panel->shortcuts[row]);
353 panel->shortcuts[row] = NULL;
354 WMRedisplayWidget(panel->actLs);
358 static void typedKeys(void *observerData, WMNotification * notification)
360 _Panel *panel = (_Panel *) observerData;
361 int row = WMGetListSelectedItemRow(panel->actLs);
363 if (row < 0)
364 return;
366 if (panel->shortcuts[row])
367 wfree(panel->shortcuts[row]);
368 panel->shortcuts[row] = WMGetTextFieldText(panel->shoT);
369 if (strlen(panel->shortcuts[row]) == 0) {
370 wfree(panel->shortcuts[row]);
371 panel->shortcuts[row] = NULL;
373 WMRedisplayWidget(panel->actLs);
376 static void listClick(WMWidget * w, void *data)
378 _Panel *panel = (_Panel *) data;
379 int row = WMGetListSelectedItemRow(w);
381 WMSetTextFieldText(panel->shoT, panel->shortcuts[row]);
384 static void showData(_Panel * panel)
386 char *str;
387 int i;
389 for (i = 0; i < panel->actionCount; i++) {
391 str = GetStringForKey(keyOptions[i]);
392 if (panel->shortcuts[i])
393 wfree(panel->shortcuts[i]);
394 if (str)
395 panel->shortcuts[i] = wtrimspace(str);
396 else
397 panel->shortcuts[i] = NULL;
399 if (panel->shortcuts[i] &&
400 (strcasecmp(panel->shortcuts[i], "none") == 0 || strlen(panel->shortcuts[i]) == 0)) {
401 wfree(panel->shortcuts[i]);
402 panel->shortcuts[i] = NULL;
405 WMRedisplayWidget(panel->actLs);
408 static void paintItem(WMList * lPtr, int index, Drawable d, char *text, int state, WMRect * rect)
410 int width, height, x, y;
411 _Panel *panel = (_Panel *) WMGetHangedData(lPtr);
412 WMScreen *scr = WMWidgetScreen(lPtr);
413 Display *dpy = WMScreenDisplay(scr);
414 WMColor *backColor = (state & WLDSSelected) ? panel->white : panel->gray;
416 width = rect->size.width;
417 height = rect->size.height;
418 x = rect->pos.x;
419 y = rect->pos.y;
421 XFillRectangle(dpy, d, WMColorGC(backColor), x, y, width, height);
423 if (panel->shortcuts[index]) {
424 WMPixmap *pix = WMGetSystemPixmap(scr, WSICheckMark);
425 WMSize size = WMGetPixmapSize(pix);
427 WMDrawPixmap(pix, d, x + (20 - size.width) / 2, (height - size.height) / 2 + y);
428 WMReleasePixmap(pix);
431 WMDrawString(scr, d, panel->black, panel->font, x + 20, y, text, strlen(text));
434 static void createPanel(Panel * p)
436 _Panel *panel = (_Panel *) p;
437 WMScreen *scr = WMWidgetScreen(panel->parent);
438 WMColor *color;
439 WMFont *boldFont;
441 panel->capturing = 0;
443 panel->white = WMWhiteColor(scr);
444 panel->black = WMBlackColor(scr);
445 panel->gray = WMGrayColor(scr);
446 panel->font = WMSystemFontOfSize(scr, 12);
448 panel->box = WMCreateBox(panel->parent);
449 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
451 boldFont = WMBoldSystemFontOfSize(scr, 12);
453 /* **************** Actions **************** */
454 panel->actL = WMCreateLabel(panel->box);
455 WMResizeWidget(panel->actL, 280, 20);
456 WMMoveWidget(panel->actL, 20, 10);
457 WMSetLabelFont(panel->actL, boldFont);
458 WMSetLabelText(panel->actL, _("Actions"));
459 WMSetLabelRelief(panel->actL, WRSunken);
460 WMSetLabelTextAlignment(panel->actL, WACenter);
461 color = WMDarkGrayColor(scr);
462 WMSetWidgetBackgroundColor(panel->actL, color);
463 WMReleaseColor(color);
464 WMSetLabelTextColor(panel->actL, panel->white);
466 panel->actLs = WMCreateList(panel->box);
467 WMResizeWidget(panel->actLs, 280, 190);
468 WMMoveWidget(panel->actLs, 20, 32);
469 WMSetListUserDrawProc(panel->actLs, paintItem);
470 WMHangData(panel->actLs, panel);
472 WMAddListItem(panel->actLs, _("Open applications menu"));
473 WMAddListItem(panel->actLs, _("Open window list menu"));
474 WMAddListItem(panel->actLs, _("Open window commands menu"));
475 WMAddListItem(panel->actLs, _("Hide active application"));
476 WMAddListItem(panel->actLs, _("Hide other applications"));
477 WMAddListItem(panel->actLs, _("Miniaturize active window"));
478 WMAddListItem(panel->actLs, _("Miniaturize all windows"));
479 WMAddListItem(panel->actLs, _("Close active window"));
480 WMAddListItem(panel->actLs, _("Maximize active window"));
481 WMAddListItem(panel->actLs, _("Maximize active window vertically"));
482 WMAddListItem(panel->actLs, _("Maximize active window horizontally"));
483 WMAddListItem(panel->actLs, _("Maximize active window left half"));
484 WMAddListItem(panel->actLs, _("Maximize active window right half"));
485 WMAddListItem(panel->actLs, _("Maximus: Tiled maximization "));
486 WMAddListItem(panel->actLs, _("Raise active window"));
487 WMAddListItem(panel->actLs, _("Lower active window"));
488 WMAddListItem(panel->actLs, _("Raise/Lower window under mouse pointer"));
489 WMAddListItem(panel->actLs, _("Shade active window"));
490 WMAddListItem(panel->actLs, _("Move/Resize active window"));
491 WMAddListItem(panel->actLs, _("Select active window"));
492 WMAddListItem(panel->actLs, _("Focus next window"));
493 WMAddListItem(panel->actLs, _("Focus previous window"));
494 WMAddListItem(panel->actLs, _("Focus next group window"));
495 WMAddListItem(panel->actLs, _("Focus previous group window"));
496 WMAddListItem(panel->actLs, _("Switch to next workspace"));
497 WMAddListItem(panel->actLs, _("Switch to previous workspace"));
498 WMAddListItem(panel->actLs, _("Switch to last used workspace"));
499 WMAddListItem(panel->actLs, _("Switch to next ten workspaces"));
500 WMAddListItem(panel->actLs, _("Switch to previous ten workspaces"));
501 WMAddListItem(panel->actLs, _("Switch to workspace 1"));
502 WMAddListItem(panel->actLs, _("Switch to workspace 2"));
503 WMAddListItem(panel->actLs, _("Switch to workspace 3"));
504 WMAddListItem(panel->actLs, _("Switch to workspace 4"));
505 WMAddListItem(panel->actLs, _("Switch to workspace 5"));
506 WMAddListItem(panel->actLs, _("Switch to workspace 6"));
507 WMAddListItem(panel->actLs, _("Switch to workspace 7"));
508 WMAddListItem(panel->actLs, _("Switch to workspace 8"));
509 WMAddListItem(panel->actLs, _("Switch to workspace 9"));
510 WMAddListItem(panel->actLs, _("Switch to workspace 10"));
511 WMAddListItem(panel->actLs, _("Move window to next workspace"));
512 WMAddListItem(panel->actLs, _("Move window to previous workspace"));
513 WMAddListItem(panel->actLs, _("Move window to last used workspace"));
514 WMAddListItem(panel->actLs, _("Move window to next ten workspaces"));
515 WMAddListItem(panel->actLs, _("Move window to previous ten workspaces"));
516 WMAddListItem(panel->actLs, _("Move window to workspace 1"));
517 WMAddListItem(panel->actLs, _("Move window to workspace 2"));
518 WMAddListItem(panel->actLs, _("Move window to workspace 3"));
519 WMAddListItem(panel->actLs, _("Move window to workspace 4"));
520 WMAddListItem(panel->actLs, _("Move window to workspace 5"));
521 WMAddListItem(panel->actLs, _("Move window to workspace 6"));
522 WMAddListItem(panel->actLs, _("Move window to workspace 7"));
523 WMAddListItem(panel->actLs, _("Move window to workspace 8"));
524 WMAddListItem(panel->actLs, _("Move window to workspace 9"));
525 WMAddListItem(panel->actLs, _("Move window to workspace 10"));
526 WMAddListItem(panel->actLs, _("Shortcut for window 1"));
527 WMAddListItem(panel->actLs, _("Shortcut for window 2"));
528 WMAddListItem(panel->actLs, _("Shortcut for window 3"));
529 WMAddListItem(panel->actLs, _("Shortcut for window 4"));
530 WMAddListItem(panel->actLs, _("Shortcut for window 5"));
531 WMAddListItem(panel->actLs, _("Shortcut for window 6"));
532 WMAddListItem(panel->actLs, _("Shortcut for window 7"));
533 WMAddListItem(panel->actLs, _("Shortcut for window 8"));
534 WMAddListItem(panel->actLs, _("Shortcut for window 9"));
535 WMAddListItem(panel->actLs, _("Shortcut for window 10"));
536 WMAddListItem(panel->actLs, _("Launch new instance of application"));
537 WMAddListItem(panel->actLs, _("Switch to Next Screen/Monitor"));
538 WMAddListItem(panel->actLs, _("Raise/Lower Dock"));
539 WMAddListItem(panel->actLs, _("Raise/Lower Clip"));
540 #ifdef XKB_MODELOCK
541 WMAddListItem(panel->actLs, _("Toggle keyboard language"));
542 #endif /* XKB_MODELOCK */
544 WMSetListAction(panel->actLs, listClick, panel);
546 panel->actionCount = WMGetListNumberOfRows(panel->actLs);
547 panel->shortcuts = wmalloc(sizeof(char *) * panel->actionCount);
549 /***************** Shortcut ****************/
551 panel->shoF = WMCreateFrame(panel->box);
552 WMResizeWidget(panel->shoF, 190, 210);
553 WMMoveWidget(panel->shoF, 315, 10);
554 WMSetFrameTitle(panel->shoF, _("Shortcut"));
556 panel->shoT = WMCreateTextField(panel->shoF);
557 WMResizeWidget(panel->shoT, 160, 20);
558 WMMoveWidget(panel->shoT, 15, 65);
559 WMAddNotificationObserver(typedKeys, panel, WMTextDidChangeNotification, panel->shoT);
561 panel->cleB = WMCreateCommandButton(panel->shoF);
562 WMResizeWidget(panel->cleB, 75, 24);
563 WMMoveWidget(panel->cleB, 15, 95);
564 WMSetButtonText(panel->cleB, _("Clear"));
565 WMSetButtonAction(panel->cleB, clearShortcut, panel);
567 panel->defB = WMCreateCommandButton(panel->shoF);
568 WMResizeWidget(panel->defB, 75, 24);
569 WMMoveWidget(panel->defB, 100, 95);
570 WMSetButtonText(panel->defB, _("Capture"));
571 WMSetButtonAction(panel->defB, captureClick, panel);
573 panel->instructionsL = WMCreateLabel(panel->shoF);
574 WMResizeWidget(panel->instructionsL, 160, 55);
575 WMMoveWidget(panel->instructionsL, 15, 140);
576 WMSetLabelTextAlignment(panel->instructionsL, WACenter);
577 WMSetLabelWraps(panel->instructionsL, True);
578 WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
580 WMMapSubwidgets(panel->shoF);
582 WMReleaseFont(boldFont);
584 WMRealizeWidget(panel->box);
585 WMMapSubwidgets(panel->box);
587 showData(panel);
590 static void storeData(_Panel * panel)
592 int i;
593 char *str;
595 for (i = 0; i < panel->actionCount; i++) {
596 str = NULL;
597 if (panel->shortcuts[i]) {
598 str = wtrimspace(panel->shortcuts[i]);
599 if (strlen(str) == 0) {
600 wfree(str);
601 str = NULL;
604 if (str) {
605 SetStringForKey(str, keyOptions[i]);
606 wfree(str);
607 } else {
608 SetStringForKey("None", keyOptions[i]);
613 Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent)
615 _Panel *panel;
617 panel = wmalloc(sizeof(_Panel));
619 panel->sectionName = _("Keyboard Shortcut Preferences");
621 panel->description = _("Change the keyboard shortcuts for actions such\n"
622 "as changing workspaces and opening menus.");
624 panel->parent = parent;
626 panel->callbacks.createWidgets = createPanel;
627 panel->callbacks.updateDomain = storeData;
629 AddSection(panel, ICON_FILE);
631 return panel;