2 /* MouseSettings.c- mouse options (some are equivalent to xset)
4 * WPrefs - Window Maker Preferences Program
6 * Copyright (c) 1998-2003 Alfredo K. Kojima
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 #include <X11/Xutil.h>
31 /* double-click tester */
36 typedef struct _Panel
{
43 CallbackRec callbacks
;
66 WMPopUpButton
*button1P
;
67 WMPopUpButton
*button2P
;
68 WMPopUpButton
*button3P
;
69 WMPopUpButton
*wheelP
;
76 /**/ int maxThreshold
;
80 #define ICON_FILE "mousesettings"
82 #define SPEED_ICON_FILE "mousespeed"
84 #define DELAY_ICON "timer%i"
85 #define DELAY_ICON_S "timer%is"
87 /* need access to the double click variables */
88 #include <WINGs/WINGsP.h>
90 static char *modifierNames
[8];
92 static char *buttonActions
[4];
94 static char *wheelActions
[2];
96 #define DELAY(i) ((i)*75+170)
98 int ModifierFromKey(Display
* dpy
, char *key
);
100 static void setMouseAccel(WMScreen
* scr
, float accel
, int threshold
)
107 XChangePointerControl(WMScreenDisplay(scr
), True
, True
, n
, d
, threshold
);
110 static void speedChange(WMWidget
* w
, void *data
)
112 _Panel
*panel
= (_Panel
*) data
;
121 tmp
= WMGetTextFieldText(panel
->acceT
);
122 if (sscanf(tmp
, "%f", &accel
) != 1 || accel
< 0) {
123 WMRunAlertPanel(WMWidgetScreen(panel
->acceT
), GetWindow(panel
),
125 _("Invalid mouse acceleration value. Must be a positive real value."),
126 _("OK"), NULL
, NULL
);
130 panel
->acceleration
= accel
;
133 i
= (int)WMGetSliderValue(panel
->speedS
);
135 panel
->acceleration
= 0.25 + (i
* 0.25);
137 sprintf(buffer
, "%.2f", 0.25 + (i
* 0.25));
138 WMSetTextFieldText(panel
->acceT
, buffer
);
141 tmp
= WMGetTextFieldText(panel
->threT
);
142 if (sscanf(tmp
, "%i", &threshold
) != 1 || threshold
< 0 || threshold
> panel
->maxThreshold
) {
143 WMRunAlertPanel(WMWidgetScreen(panel
->parent
), GetWindow(panel
), _("Error"),
145 ("Invalid mouse acceleration threshold value. Must be the number of pixels to travel before accelerating."),
146 _("OK"), NULL
, NULL
);
148 setMouseAccel(WMWidgetScreen(panel
->parent
), panel
->acceleration
, threshold
);
153 static void returnPressed(void *observerData
, WMNotification
* notification
)
155 _Panel
*panel
= (_Panel
*) observerData
;
157 speedChange(NULL
, panel
);
160 static void doubleClick(WMWidget
* w
, void *data
)
162 _Panel
*panel
= (_Panel
*) data
;
164 extern _WINGsConfiguration WINGsConfiguration
;
167 for (i
= 0; i
< 5; i
++) {
168 if (panel
->ddelaB
[i
] == w
)
171 WINGsConfiguration
.doubleClickDelay
= DELAY(i
);
173 sprintf(buffer
, "%i", DELAY(i
));
174 WMSetTextFieldText(panel
->ddelaT
, buffer
);
177 static int getButtonAction(char *str
)
182 if (strcasecmp(str
, "None") == 0)
184 else if (strcasecmp(str
, "OpenApplicationsMenu") == 0)
186 else if (strcasecmp(str
, "OpenWindowListMenu") == 0)
188 else if (strcasecmp(str
, "SelectWindows") == 0)
195 static int getWheelAction(char *str
)
200 if (strcasecmp(str
, "None") == 0)
202 else if (strcasecmp(str
, "SwitchWorkspaces") == 0)
209 static void getMouseParameters(Display
* dpy
, float *accel
, int *thre
)
213 XGetPointerControl(dpy
, &n
, &d
, thre
);
215 *accel
= (float)n
/ (float)d
;
218 static void showData(_Panel
* panel
)
222 int a
= -1, b
= -1, c
= -1, w
= -1;
225 Display
*dpy
= WMScreenDisplay(WMWidgetScreen(panel
->parent
));
227 str
= GetStringForKey("MouseLeftButtonAction");
228 i
= getButtonAction(str
);
232 wwarning(_("bad value %s for option %s"), str
, "MouseLeftButtonAction");
237 WMSetPopUpButtonSelectedItem(panel
->button1P
, a
);
239 str
= GetStringForKey("MouseMiddleButtonAction");
240 i
= getButtonAction(str
);
244 wwarning(_("bad value %s for option %s"), str
, "MouseMiddleButtonAction");
249 WMSetPopUpButtonSelectedItem(panel
->button2P
, b
);
251 str
= GetStringForKey("MouseRightButtonAction");
252 i
= getButtonAction(str
);
256 wwarning(_("bad value %s for option %s"), str
, "MouseRightButtonAction");
261 WMSetPopUpButtonSelectedItem(panel
->button3P
, c
);
263 str
= GetStringForKey("MouseWheelAction");
264 i
= getWheelAction(str
);
268 wwarning(_("bad value %s for option %s"), str
, "MouseWheelAction");
273 WMSetPopUpButtonSelectedItem(panel
->wheelP
, w
);
275 WMSetButtonSelected(panel
->disaB
, GetBoolForKey("DisableWSMouseActions"));
277 /**/ getMouseParameters(dpy
, &accel
, &a
);
278 panel
->maxThreshold
= WidthOfScreen(DefaultScreenOfDisplay(dpy
));
279 if (a
> panel
->maxThreshold
) {
280 panel
->maxThreshold
= a
;
282 sprintf(buffer
, "%i", a
);
283 WMSetTextFieldText(panel
->threT
, buffer
);
285 WMSetSliderValue(panel
->speedS
, (accel
- 0.25) / 0.25);
287 panel
->acceleration
= accel
;
288 sprintf(buffer
, "%.2f", accel
);
289 WMSetTextFieldText(panel
->acceT
, buffer
);
291 /**/ b
= GetIntegerForKey("DoubleClickTime");
292 /* find best match */
294 for (i
= 0; i
< 5; i
++) {
299 WMPerformButtonClick(panel
->ddelaB
[a
]);
300 sprintf(buffer
, "%i", b
);
301 WMSetTextFieldText(panel
->ddelaT
, buffer
);
303 /**/ str
= GetStringForKey("ModifierKey");
306 a
= ModifierFromKey(dpy
, str
);
309 str
= modifierNames
[a
];
312 for (i
= 0; i
< WMGetPopUpButtonNumberOfItems(panel
->grabP
); i
++) {
313 if (strstr(WMGetPopUpButtonItem(panel
->grabP
, i
), str
)) {
314 WMSetPopUpButtonSelectedItem(panel
->grabP
, i
);
322 sscanf(WMGetPopUpButtonItem(panel
->grabP
, 0), "%s", buffer
);
323 WMSetPopUpButtonSelectedItem(panel
->grabP
, 0);
324 wwarning(_("modifier key %s for option ModifierKey was not recognized. Using %s as default"),
329 static void fillModifierPopUp(WMPopUpButton
* pop
)
331 XModifierKeymap
*mapping
;
332 Display
*dpy
= WMScreenDisplay(WMWidgetScreen(pop
));
337 mapping
= XGetModifierMapping(dpy
);
339 if (!mapping
|| mapping
->max_keypermod
== 0) {
340 WMAddPopUpButtonItem(pop
, "Mod1");
341 WMAddPopUpButtonItem(pop
, "Mod2");
342 WMAddPopUpButtonItem(pop
, "Mod3");
343 WMAddPopUpButtonItem(pop
, "Mod4");
344 WMAddPopUpButtonItem(pop
, "Mod5");
345 wwarning(_("could not retrieve keyboard modifier mapping"));
349 for (j
= 0; j
< 8; j
++) {
359 memset(array
, 0, sizeof(char *) * 8);
360 for (i
= 0; i
< mapping
->max_keypermod
; i
++) {
361 idx
= i
+ j
* mapping
->max_keypermod
;
362 if (mapping
->modifiermap
[idx
] != 0) {
364 for (l
= 0; l
< 4; l
++) {
365 ksym
= XKeycodeToKeysym(dpy
, mapping
->modifiermap
[idx
], l
);
366 if (ksym
!= NoSymbol
)
369 if (ksym
!= NoSymbol
)
370 str
= XKeysymToString(ksym
);
373 if (str
&& !strstr(str
, "_Lock") && !strstr(str
, "Shift")
374 && !strstr(str
, "Control")) {
375 array
[a
++] = wstrdup(str
);
380 for (k
= 0; k
< a
; k
++) {
381 if (array
[k
] == NULL
)
383 tmp
= wstrdup(array
[k
]);
384 ptr
= strstr(tmp
, "_L");
387 ptr
= strstr(tmp
, "_R");
390 sprintf(buffer
, "%s (%s)", modifierNames
[j
], tmp
);
391 /*sprintf(buffer, "%s", tmp); */
392 WMAddPopUpButtonItem(pop
, buffer
);
393 for (i
= k
+ 1; i
< a
; i
++) {
394 if (array
[i
] == NULL
)
396 if (strstr(array
[i
], tmp
)) {
412 XFreeModifiermap(mapping
);
415 static void createPanel(Panel
* p
)
417 _Panel
*panel
= (_Panel
*) p
;
418 WMScreen
*scr
= WMWidgetScreen(panel
->parent
);
429 panel
->box
= WMCreateBox(panel
->parent
);
430 WMSetViewExpandsToParent(WMWidgetView(panel
->box
), 2, 2, 2, 2);
432 /**************** Mouse Speed ****************/
433 panel
->speedF
= WMCreateFrame(panel
->box
);
434 WMResizeWidget(panel
->speedF
, 245, 100);
435 WMMoveWidget(panel
->speedF
, 15, 5);
436 WMSetFrameTitle(panel
->speedF
, _("Mouse Speed"));
438 panel
->speedL
= WMCreateLabel(panel
->speedF
);
439 WMResizeWidget(panel
->speedL
, 40, 46);
440 WMMoveWidget(panel
->speedL
, 15, 14);
441 WMSetLabelImagePosition(panel
->speedL
, WIPImageOnly
);
442 path
= LocateImage(SPEED_ICON_FILE
);
444 icon
= WMCreateBlendedPixmapFromFile(scr
, path
, &color
);
446 WMSetLabelImage(panel
->speedL
, icon
);
447 WMReleasePixmap(icon
);
449 wwarning(_("could not load icon %s"), path
);
454 panel
->speedS
= WMCreateSlider(panel
->speedF
);
455 WMResizeWidget(panel
->speedS
, 160, 15);
456 WMMoveWidget(panel
->speedS
, 70, 35);
457 WMSetSliderMinValue(panel
->speedS
, 0);
458 WMSetSliderMaxValue(panel
->speedS
, 40);
459 WMSetSliderContinuous(panel
->speedS
, False
);
460 WMSetSliderAction(panel
->speedS
, speedChange
, panel
);
462 panel
->acceL
= WMCreateLabel(panel
->speedF
);
463 WMResizeWidget(panel
->acceL
, 70, 16);
464 WMMoveWidget(panel
->acceL
, 10, 67);
465 WMSetLabelTextAlignment(panel
->acceL
, WARight
);
466 WMSetLabelText(panel
->acceL
, _("Acceler.:"));
468 panel
->acceT
= WMCreateTextField(panel
->speedF
);
469 WMResizeWidget(panel
->acceT
, 40, 20);
470 WMMoveWidget(panel
->acceT
, 80, 65);
471 WMAddNotificationObserver(returnPressed
, panel
, WMTextDidEndEditingNotification
, panel
->acceT
);
473 panel
->threL
= WMCreateLabel(panel
->speedF
);
474 WMResizeWidget(panel
->threL
, 80, 16);
475 WMMoveWidget(panel
->threL
, 120, 67);
476 WMSetLabelTextAlignment(panel
->threL
, WARight
);
477 WMSetLabelText(panel
->threL
, _("Threshold:"));
479 panel
->threT
= WMCreateTextField(panel
->speedF
);
480 WMResizeWidget(panel
->threT
, 30, 20);
481 WMMoveWidget(panel
->threT
, 200, 65);
482 WMAddNotificationObserver(returnPressed
, panel
, WMTextDidEndEditingNotification
, panel
->threT
);
484 WMMapSubwidgets(panel
->speedF
);
486 /***************** Doubleclick Delay ****************/
488 panel
->ddelaF
= WMCreateFrame(panel
->box
);
489 WMResizeWidget(panel
->ddelaF
, 245, 105);
490 WMMoveWidget(panel
->ddelaF
, 15, 115);
491 WMSetFrameTitle(panel
->ddelaF
, _("Double-Click Delay"));
493 buf1
= wmalloc(strlen(DELAY_ICON
) + 2);
494 buf2
= wmalloc(strlen(DELAY_ICON_S
) + 2);
496 for (i
= 0; i
< 5; i
++) {
497 panel
->ddelaB
[i
] = WMCreateCustomButton(panel
->ddelaF
, WBBStateChangeMask
);
498 WMResizeWidget(panel
->ddelaB
[i
], 25, 25);
499 WMMoveWidget(panel
->ddelaB
[i
], 30 + (40 * i
), 25);
500 WMSetButtonBordered(panel
->ddelaB
[i
], False
);
501 WMSetButtonImagePosition(panel
->ddelaB
[i
], WIPImageOnly
);
502 WMSetButtonAction(panel
->ddelaB
[i
], doubleClick
, panel
);
504 WMGroupButtons(panel
->ddelaB
[0], panel
->ddelaB
[i
]);
506 sprintf(buf1
, DELAY_ICON
, i
+ 1);
507 sprintf(buf2
, DELAY_ICON_S
, i
+ 1);
508 path
= LocateImage(buf1
);
510 icon
= WMCreatePixmapFromFile(scr
, path
);
512 WMSetButtonImage(panel
->ddelaB
[i
], icon
);
513 WMReleasePixmap(icon
);
515 wwarning(_("could not load icon file %s"), path
);
519 path
= LocateImage(buf2
);
521 icon
= WMCreatePixmapFromFile(scr
, path
);
523 WMSetButtonAltImage(panel
->ddelaB
[i
], icon
);
524 WMReleasePixmap(icon
);
526 wwarning(_("could not load icon file %s"), path
);
534 panel
->tester
= CreateDoubleTest(panel
->ddelaF
, _("Test"));
535 WMResizeWidget(panel
->tester
, 84, 29);
536 WMMoveWidget(panel
->tester
, 35, 60);
538 panel
->ddelaT
= WMCreateTextField(panel
->ddelaF
);
539 WMResizeWidget(panel
->ddelaT
, 40, 20);
540 WMMoveWidget(panel
->ddelaT
, 140, 65);
542 panel
->ddelaL
= WMCreateLabel(panel
->ddelaF
);
543 WMResizeWidget(panel
->ddelaL
, 40, 16);
544 WMMoveWidget(panel
->ddelaL
, 185, 70);
549 font
= WMSystemFontOfSize(scr
, 10);
550 color
= WMDarkGrayColor(scr
);
551 WMSetLabelTextColor(panel
->ddelaL
, color
);
552 WMSetLabelFont(panel
->ddelaL
, font
);
554 WMReleaseColor(color
);
556 WMSetLabelText(panel
->ddelaL
, _("msec"));
558 WMMapSubwidgets(panel
->ddelaF
);
560 /* ************** Workspace Action Buttons **************** */
561 panel
->menuF
= WMCreateFrame(panel
->box
);
562 WMResizeWidget(panel
->menuF
, 240, 160);
563 WMMoveWidget(panel
->menuF
, 270, 5);
564 WMSetFrameTitle(panel
->menuF
, _("Workspace Mouse Actions"));
566 panel
->disaB
= WMCreateSwitchButton(panel
->menuF
);
567 WMResizeWidget(panel
->disaB
, 205, 18);
568 WMMoveWidget(panel
->disaB
, 10, 18);
569 WMSetButtonText(panel
->disaB
, _("Disable mouse actions"));
571 panel
->button1L
= WMCreateLabel(panel
->menuF
);
572 WMResizeWidget(panel
->button1L
, 87, 20);
573 WMMoveWidget(panel
->button1L
, 5, 45);
574 WMSetLabelTextAlignment(panel
->button1L
, WARight
);
575 WMSetLabelText(panel
->button1L
, _("Left Button"));
577 panel
->button1P
= WMCreatePopUpButton(panel
->menuF
);
578 WMResizeWidget(panel
->button1P
, 135, 20);
579 WMMoveWidget(panel
->button1P
, 95, 45);
581 panel
->button2L
= WMCreateLabel(panel
->menuF
);
582 WMResizeWidget(panel
->button2L
, 87, 20);
583 WMMoveWidget(panel
->button2L
, 5, 73);
584 WMSetLabelTextAlignment(panel
->button2L
, WARight
);
585 WMSetLabelText(panel
->button2L
, _("Middle Button"));
587 panel
->button2P
= WMCreatePopUpButton(panel
->menuF
);
588 WMResizeWidget(panel
->button2P
, 135, 20);
589 WMMoveWidget(panel
->button2P
, 95, 73);
591 panel
->button3L
= WMCreateLabel(panel
->menuF
);
592 WMResizeWidget(panel
->button3L
, 87, 20);
593 WMMoveWidget(panel
->button3L
, 5, 101);
594 WMSetLabelTextAlignment(panel
->button3L
, WARight
);
595 WMSetLabelText(panel
->button3L
, _("Right Button"));
597 panel
->button3P
= WMCreatePopUpButton(panel
->menuF
);
598 WMResizeWidget(panel
->button3P
, 135, 20);
599 WMMoveWidget(panel
->button3P
, 95, 101);
601 panel
->wheelL
= WMCreateLabel(panel
->menuF
);
602 WMResizeWidget(panel
->wheelL
, 87, 20);
603 WMMoveWidget(panel
->wheelL
, 5, 129);
604 WMSetLabelTextAlignment(panel
->wheelL
, WARight
);
605 WMSetLabelText(panel
->wheelL
, _("Mouse Wheel"));
607 panel
->wheelP
= WMCreatePopUpButton(panel
->menuF
);
608 WMResizeWidget(panel
->wheelP
, 135, 20);
609 WMMoveWidget(panel
->wheelP
, 95, 129);
611 for (i
= 0; i
< sizeof(buttonActions
) / sizeof(char *); i
++) {
612 WMAddPopUpButtonItem(panel
->button1P
, buttonActions
[i
]);
613 WMAddPopUpButtonItem(panel
->button2P
, buttonActions
[i
]);
614 WMAddPopUpButtonItem(panel
->button3P
, buttonActions
[i
]);
617 for (i
= 0; i
< sizeof(wheelActions
) / sizeof(char *); i
++) {
618 WMAddPopUpButtonItem(panel
->wheelP
, wheelActions
[i
]);
621 WMMapSubwidgets(panel
->menuF
);
623 /* ************** Grab Modifier **************** */
624 panel
->grabF
= WMCreateFrame(panel
->box
);
625 WMResizeWidget(panel
->grabF
, 240, 50);
626 WMMoveWidget(panel
->grabF
, 270, 170);
627 WMSetFrameTitle(panel
->grabF
, _("Mouse Grab Modifier"));
629 WMSetBalloonTextForView(_("Keyboard modifier to use for actions that\n"
630 "involve dragging windows with the mouse,\n"
631 "clicking inside the window."), WMWidgetView(panel
->grabF
));
633 panel
->grabP
= WMCreatePopUpButton(panel
->grabF
);
634 WMResizeWidget(panel
->grabP
, 160, 20);
635 WMMoveWidget(panel
->grabP
, 40, 20);
637 fillModifierPopUp(panel
->grabP
);
639 WMMapSubwidgets(panel
->grabF
);
641 WMRealizeWidget(panel
->box
);
642 WMMapSubwidgets(panel
->box
);
647 static void storeCommandInScript(char *cmd
, char *line
)
653 path
= wstrconcat(wusergnusteppath(), "/Library/WindowMaker/autostart");
655 f
= fopen(path
, "rb");
657 f
= fopen(path
, "wb");
659 wsyserror(_("could not create %s"), path
);
662 fprintf(f
, "#!/bin/sh\n");
666 int len
= strlen(cmd
);
671 tmppath
= wstrconcat(wusergnusteppath(), "/Library/WindowMaker/autostart.tmp");
672 fo
= fopen(tmppath
, "wb");
674 wsyserror(_("could not create temporary file %s"), tmppath
);
680 if (!fgets(buffer
, 127, f
)) {
683 if (buffer
[0] == '\n') {
684 /* don't write empty lines, else the file will grow
685 * indefinitely (one '\n' added at end of file on each save).
689 if (strncmp(buffer
, cmd
, len
) == 0) {
706 if (rename(tmppath
, path
) != 0) {
707 wsyserror(_("could not rename file %s to %s\n"), tmppath
, path
);
711 sprintf(buffer
, "chmod u+x %s", path
);
717 fsync(fileno(f
)); /* this may be rw */
722 static void storeData(_Panel
* panel
)
727 static char *button
[4] = { "None", "OpenApplicationsMenu", "OpenWindowListMenu", "SelectWindows" };
728 static char *wheel
[2] = { "None", "SwitchWorkspaces" };
729 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
731 if (!WMGetUDBoolForKey(udb
, "NoXSetStuff")) {
732 tmp
= WMGetTextFieldText(panel
->threT
);
733 if (strlen(tmp
) == 0) {
738 sprintf(buffer
, XSET
" m %i/%i %s\n", (int)(panel
->acceleration
* 10), 10, tmp
);
739 storeCommandInScript(XSET
" m", buffer
);
744 tmp
= WMGetTextFieldText(panel
->ddelaT
);
745 if (sscanf(tmp
, "%i", &i
) == 1 && i
> 0)
746 SetIntegerForKey(i
, "DoubleClickTime");
748 SetBoolForKey(WMGetButtonSelected(panel
->disaB
), "DisableWSMouseActions");
750 i
= WMGetPopUpButtonSelectedItem(panel
->button1P
);
751 SetStringForKey(button
[i
], "MouseLeftButtonAction");
753 i
= WMGetPopUpButtonSelectedItem(panel
->button2P
);
754 SetStringForKey(button
[i
], "MouseMiddleButtonAction");
756 i
= WMGetPopUpButtonSelectedItem(panel
->button3P
);
757 SetStringForKey(button
[i
], "MouseRightButtonAction");
759 i
= WMGetPopUpButtonSelectedItem(panel
->wheelP
);
760 SetStringForKey(wheel
[i
], "MouseWheelAction");
762 tmp
= WMGetPopUpButtonItem(panel
->grabP
, WMGetPopUpButtonSelectedItem(panel
->grabP
));
764 p
= strchr(tmp
, ' ');
767 SetStringForKey(tmp
, "ModifierKey");
772 Panel
*InitMouseSettings(WMScreen
* scr
, WMWidget
* parent
)
776 modifierNames
[0] = wstrdup(_("Shift"));
777 modifierNames
[1] = wstrdup(_("Lock"));
778 modifierNames
[2] = wstrdup(_("Control"));
779 modifierNames
[3] = wstrdup(_("Mod1"));
780 modifierNames
[4] = wstrdup(_("Mod2"));
781 modifierNames
[5] = wstrdup(_("Mod3"));
782 modifierNames
[6] = wstrdup(_("Mod4"));
783 modifierNames
[7] = wstrdup(_("Mod5"));
785 buttonActions
[0] = wstrdup(_("None"));
786 buttonActions
[1] = wstrdup(_("Applications Menu"));
787 buttonActions
[2] = wstrdup(_("Window List Menu"));
788 buttonActions
[3] = wstrdup(_("Select Windows"));
790 wheelActions
[0] = wstrdup(_("None"));
791 wheelActions
[1] = wstrdup(_("Switch Workspaces"));
793 panel
= wmalloc(sizeof(_Panel
));
794 memset(panel
, 0, sizeof(_Panel
));
796 panel
->sectionName
= _("Mouse Preferences");
798 panel
->description
= _("Mouse speed/acceleration, double click delay,\n" "mouse button bindings etc.");
800 panel
->parent
= parent
;
802 panel
->callbacks
.createWidgets
= createPanel
;
803 panel
->callbacks
.updateDomain
= storeData
;
805 AddSection(panel
, ICON_FILE
);