1 /* HotCornerShortcuts.c - screen corners actions
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 2023 Window Maker Team
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.
24 typedef struct _Panel
{
31 CallbackRec callbacks
;
46 WMButton
*hcdelayB
[5];
47 WMTextField
*hcdelayT
;
52 WMTextField
*hcactionsT
[4];
54 char hotcornerDelaySelected
;
57 #define ICON_FILE "hotcorners"
59 #define DELAY_ICON "timer%i"
60 #define DELAY_ICON_S "timer%is"
62 static void edgeCallback(WMWidget
* w
, void *data
)
64 _Panel
*panel
= (_Panel
*) data
;
68 /* Parameter not used, but tell the compiler that it is ok */
71 i
= WMGetSliderValue(panel
->hceS
);
74 sprintf(buffer
, _("OFF"));
76 sprintf(buffer
, _("1 pixel"));
79 sprintf(buffer
, _("%i pixels"), i
);
82 sprintf(buffer
, _("%i pixels "), i
); /* note space! */
83 WMSetLabelText(panel
->hceL
, buffer
);
86 static void showData(_Panel
* panel
)
92 if (!GetObjectForKey("HotCornerDelay"))
95 i
= GetIntegerForKey("HotCornerDelay");
96 sprintf(buffer
, "%i", i
);
97 WMSetTextFieldText(panel
->hcdelayT
, buffer
);
101 WMPerformButtonClick(panel
->hcdelayB
[0]);
104 WMPerformButtonClick(panel
->hcdelayB
[1]);
107 WMPerformButtonClick(panel
->hcdelayB
[2]);
110 WMPerformButtonClick(panel
->hcdelayB
[3]);
113 WMPerformButtonClick(panel
->hcdelayB
[4]);
117 i
= GetIntegerForKey("HotCornerEdge");
120 WMSetSliderValue(panel
->hceS
, i
);
121 edgeCallback(NULL
, panel
);
123 WMSetButtonSelected(panel
->hcB
, GetBoolForKey("HotCorners"));
125 array
= GetObjectForKey("HotCornerActions");
126 if (array
&& (!WMIsPLArray(array
) || WMGetPropListItemCount(array
) != sizeof(panel
->hcactionsT
) / sizeof(WMTextField
*))) {
127 wwarning(_("invalid data in option HotCornerActions."));
130 for (i
= 0; i
< sizeof(panel
->hcactionsT
) / sizeof(WMTextField
*); i
++)
131 if (strcasecmp(WMGetFromPLString(WMGetFromPLArray(array
, i
)), "None") != 0)
132 WMSetTextFieldText(panel
->hcactionsT
[i
], WMGetFromPLString(WMGetFromPLArray(array
, i
)));
137 static void storeData(_Panel
* panel
)
144 SetBoolForKey(WMGetButtonSelected(panel
->hcB
), "HotCorners");
146 str
= WMGetTextFieldText(panel
->hcdelayT
);
147 if (sscanf(str
, "%i", &i
) != 1)
149 SetIntegerForKey(i
, "HotCornerDelay");
152 SetIntegerForKey(WMGetSliderValue(panel
->hceS
), "HotCornerEdge");
154 list
= WMCreatePLArray(NULL
, NULL
);
155 for (i
= 0; i
< sizeof(panel
->hcactionsT
) / sizeof(WMTextField
*); i
++) {
156 str
= WMGetTextFieldText(panel
->hcactionsT
[i
]);
157 if (strlen(str
) == 0)
159 tmp
= WMCreatePLString(str
);
160 WMAddToPLArray(list
, tmp
);
162 SetObjectForKey(list
, "HotCornerActions");
165 static void pushDelayButton(WMWidget
* w
, void *data
)
167 _Panel
*panel
= (_Panel
*) data
;
169 panel
->hotcornerDelaySelected
= 1;
170 if (w
== panel
->hcdelayB
[0]) {
171 WMSetTextFieldText(panel
->hcdelayT
, "0");
172 } else if (w
== panel
->hcdelayB
[1]) {
173 WMSetTextFieldText(panel
->hcdelayT
, "250");
174 } else if (w
== panel
->hcdelayB
[2]) {
175 WMSetTextFieldText(panel
->hcdelayT
, "500");
176 } else if (w
== panel
->hcdelayB
[3]) {
177 WMSetTextFieldText(panel
->hcdelayT
, "700");
178 } else if (w
== panel
->hcdelayB
[4]) {
179 WMSetTextFieldText(panel
->hcdelayT
, "1000");
183 static void delayTextChanged(void *observerData
, WMNotification
* notification
)
185 _Panel
*panel
= (_Panel
*) observerData
;
188 /* Parameter not used, but tell the compiler that it is ok */
191 if (panel
->hotcornerDelaySelected
) {
192 for (i
= 0; i
< 5; i
++) {
193 WMSetButtonSelected(panel
->hcdelayB
[i
], False
);
195 panel
->hotcornerDelaySelected
= 0;
199 static void createPanel(Panel
* p
)
201 _Panel
*panel
= (_Panel
*) p
;
208 WMScreen
*scr
= WMWidgetScreen(panel
->parent
);
209 RContext
*rc
= WMScreenRContext(scr
);
210 GC gc
= XCreateGC(scr
->display
, WMWidgetXID(panel
->parent
), 0, NULL
);
212 path
= LocateImage(ICON_FILE
);
214 xis
= RLoadImage(rc
, path
, 0);
216 wwarning(_("could not load image file %s"), path
);
221 panel
->box
= WMCreateBox(panel
->parent
);
222 WMSetViewExpandsToParent(WMWidgetView(panel
->box
), 2, 2, 2, 2);
225 /***************** Hot Corner lelf side frames *****************/
226 panel
->hcF
= WMCreateFrame(panel
->box
);
227 WMResizeWidget(panel
->hcF
, 240, 53);
228 WMMoveWidget(panel
->hcF
, 15, 17);
230 panel
->hcB
= WMCreateSwitchButton(panel
->hcF
);
231 WMResizeWidget(panel
->hcB
, 150, 30);
232 WMMoveWidget(panel
->hcB
, 15, 12);
233 WMSetButtonText(panel
->hcB
, _("Enable Hot Corners"));
235 WMMapSubwidgets(panel
->hcF
);
237 panel
->hceF
= WMCreateFrame(panel
->box
);
238 WMSetFrameTitle(panel
->hceF
, _("Hot Corner Edge"));
239 WMResizeWidget(panel
->hceF
, 240, 40);
240 WMMoveWidget(panel
->hceF
, 15, 77);
242 panel
->hceS
= WMCreateSlider(panel
->hceF
);
243 WMResizeWidget(panel
->hceS
, 80, 15);
244 WMMoveWidget(panel
->hceS
, 15, 18);
245 WMSetSliderMinValue(panel
->hceS
, 2);
246 WMSetSliderMaxValue(panel
->hceS
, 10);
247 WMSetSliderAction(panel
->hceS
, edgeCallback
, panel
);
249 panel
->hceL
= WMCreateLabel(panel
->hceF
);
250 WMResizeWidget(panel
->hceL
, 100, 15);
251 WMMoveWidget(panel
->hceL
, 105, 18);
253 WMMapSubwidgets(panel
->hceF
);
255 panel
->hcdescF
= WMCreateFrame(panel
->box
);
256 WMResizeWidget(panel
->hcdescF
, 240, 95);
257 WMMoveWidget(panel
->hcdescF
, 15, 130);
259 panel
->hcdescL
= WMCreateLabel(panel
->hcdescF
);
260 WMResizeWidget(panel
->hcdescL
, 200, 60);
261 WMMoveWidget(panel
->hcdescL
, 15, 10);
262 WMSetLabelText(panel
->hcdescL
,
263 _("Instructions:\n\n"
264 " - assign command to corner\n"
265 " - or leave it empty\n"));
267 WMMapSubwidgets(panel
->hcdescF
);
269 /***************** Hot Corner Action Delay *****************/
270 panel
->hcdelayF
= WMCreateFrame(panel
->box
);
271 WMResizeWidget(panel
->hcdelayF
, 245, 60);
272 WMMoveWidget(panel
->hcdelayF
, 265, 10);
274 WMSetFrameTitle(panel
->hcdelayF
, _("Hot Corner Delay"));
276 buf1
= wmalloc(strlen(DELAY_ICON
) + 1);
277 buf2
= wmalloc(strlen(DELAY_ICON_S
) + 1);
279 for (i
= 0; i
< 5; i
++) {
282 panel
->hcdelayB
[i
] = WMCreateCustomButton(panel
->hcdelayF
, WBBStateChangeMask
);
283 WMResizeWidget(panel
->hcdelayB
[i
], 25, 25);
284 WMMoveWidget(panel
->hcdelayB
[i
], 12 + (30 * i
), 25);
285 WMSetButtonBordered(panel
->hcdelayB
[i
], False
);
286 WMSetButtonImagePosition(panel
->hcdelayB
[i
], WIPImageOnly
);
287 WMSetButtonAction(panel
->hcdelayB
[i
], pushDelayButton
, panel
);
289 WMGroupButtons(panel
->hcdelayB
[0], panel
->hcdelayB
[i
]);
290 sprintf(buf1
, DELAY_ICON
, i
);
291 sprintf(buf2
, DELAY_ICON_S
, i
);
292 path
= LocateImage(buf1
);
294 panel
->icon
= WMCreatePixmapFromFile(scr
, path
);
296 WMSetButtonImage(panel
->hcdelayB
[i
], panel
->icon
);
297 WMReleasePixmap(panel
->icon
);
299 wwarning(_("could not load icon file %s"), path
);
303 path
= LocateImage(buf2
);
305 panel
->icon
= WMCreatePixmapFromFile(scr
, path
);
307 WMSetButtonAltImage(panel
->hcdelayB
[i
], panel
->icon
);
308 WMReleasePixmap(panel
->icon
);
310 wwarning(_("could not load icon file %s"), path
);
318 panel
->hcdelayT
= WMCreateTextField(panel
->hcdelayF
);
320 WMResizeWidget(panel
->hcdelayT
, 36, 20);
321 WMMoveWidget(panel
->hcdelayT
, 165, 28);
322 WMAddNotificationObserver(delayTextChanged
, panel
, WMTextDidChangeNotification
, panel
->hcdelayT
);
324 panel
->hcdelayL
= WMCreateLabel(panel
->hcdelayF
);
325 WMResizeWidget(panel
->hcdelayL
, 36, 16);
326 WMMoveWidget(panel
->hcdelayL
, 205, 32);
327 WMSetLabelText(panel
->hcdelayL
, _("ms"));
329 color
= WMDarkGrayColor(scr
);
330 font
= WMSystemFontOfSize(scr
, 10);
332 WMSetLabelTextColor(panel
->hcdelayL
, color
);
333 WMSetLabelFont(panel
->hcdelayL
, font
);
335 WMReleaseColor(color
);
338 WMMapSubwidgets(panel
->hcdelayF
);
340 /***************** Set Hot Corner Actions ****************/
341 panel
->hcactionsF
= WMCreateFrame(panel
->box
);
342 WMSetFrameTitle(panel
->hcactionsF
, _("Hot Corner Actions"));
343 WMResizeWidget(panel
->hcactionsF
, 245, 148);
344 WMMoveWidget(panel
->hcactionsF
, 265, 77);
346 panel
->icornerL
= WMCreateLabel(panel
->hcactionsF
);
347 WMResizeWidget(panel
->icornerL
, 24, 24);
348 WMMoveWidget(panel
->icornerL
, 10, 18);
349 WMSetLabelImagePosition(panel
->icornerL
, WIPImageOnly
);
350 CreateImages(scr
, rc
, xis
, ICON_FILE
, &panel
->icon
, NULL
);
355 panel
->quarter
[0] = XCreatePixmap(scr
->display
, WMWidgetXID(panel
->parent
), panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
356 XCopyArea(scr
->display
, WMGetPixmapXID(panel
->icon
), panel
->quarter
[0], gc
, 0, 0, panel
->icon
->width
/2, panel
->icon
->height
/2, 0, 0);
357 nicon
= WMCreatePixmapFromXPixmaps(scr
, panel
->quarter
[0], WMGetPixmapMaskXID(panel
->icon
),
358 panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
359 WMSetLabelImage(panel
->icornerL
, nicon
);
360 WMReleasePixmap(nicon
);
363 panel
->hcactionsT
[0] = WMCreateTextField(panel
->hcactionsF
);
364 WMResizeWidget(panel
->hcactionsT
[0], 180, 20);
365 WMMoveWidget(panel
->hcactionsT
[0], 50, 20);
367 panel
->icornerL
= WMCreateLabel(panel
->hcactionsF
);
368 WMResizeWidget(panel
->icornerL
, 24, 24);
369 WMMoveWidget(panel
->icornerL
, 10, 48);
370 WMSetLabelImagePosition(panel
->icornerL
, WIPImageOnly
);
375 panel
->quarter
[1] = XCreatePixmap(scr
->display
, WMWidgetXID(panel
->parent
), panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
376 XCopyArea(scr
->display
, WMGetPixmapXID(panel
->icon
), panel
->quarter
[1], gc
, panel
->icon
->width
/2, 0, panel
->icon
->width
/2, panel
->icon
->height
/2, 0, 0);
377 nicon
= WMCreatePixmapFromXPixmaps(scr
, panel
->quarter
[1], WMGetPixmapMaskXID(panel
->icon
),
378 panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
379 WMSetLabelImage(panel
->icornerL
, nicon
);
380 WMReleasePixmap(nicon
);
383 panel
->hcactionsT
[1] = WMCreateTextField(panel
->hcactionsF
);
384 WMResizeWidget(panel
->hcactionsT
[1], 180, 20);
385 WMMoveWidget(panel
->hcactionsT
[1], 50, 50);
387 panel
->icornerL
= WMCreateLabel(panel
->hcactionsF
);
388 WMResizeWidget(panel
->icornerL
, 24, 24);
389 WMMoveWidget(panel
->icornerL
, 10, 78);
390 WMSetLabelImagePosition(panel
->icornerL
, WIPImageOnly
);
395 panel
->quarter
[2] = XCreatePixmap(scr
->display
, WMWidgetXID(panel
->parent
), panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
396 XCopyArea(scr
->display
, WMGetPixmapXID(panel
->icon
), panel
->quarter
[2], gc
, 0, panel
->icon
->height
/2, panel
->icon
->width
/2, panel
->icon
->height
/2, 0, 0);
397 nicon
= WMCreatePixmapFromXPixmaps(scr
, panel
->quarter
[2], WMGetPixmapMaskXID(panel
->icon
),
398 panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
399 WMSetLabelImage(panel
->icornerL
, nicon
);
400 WMReleasePixmap(nicon
);
402 panel
->hcactionsT
[2] = WMCreateTextField(panel
->hcactionsF
);
403 WMResizeWidget(panel
->hcactionsT
[2], 180, 20);
404 WMMoveWidget(panel
->hcactionsT
[2], 50, 80);
406 panel
->icornerL
= WMCreateLabel(panel
->hcactionsF
);
407 WMResizeWidget(panel
->icornerL
, 24, 24);
408 WMMoveWidget(panel
->icornerL
, 10, 108);
409 WMSetLabelImagePosition(panel
->icornerL
, WIPImageOnly
);
414 panel
->quarter
[3] = XCreatePixmap(scr
->display
, WMWidgetXID(panel
->parent
), panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
415 XCopyArea(scr
->display
, WMGetPixmapXID(panel
->icon
), panel
->quarter
[3], gc
, panel
->icon
->width
/2, panel
->icon
->height
/2, panel
->icon
->width
/2, panel
->icon
->height
/2, 0, 0);
416 nicon
= WMCreatePixmapFromXPixmaps(scr
, panel
->quarter
[3], WMGetPixmapMaskXID(panel
->icon
),
417 panel
->icon
->width
/2, panel
->icon
->height
/2, WMScreenDepth(scr
));
418 WMSetLabelImage(panel
->icornerL
, nicon
);
419 WMReleasePixmap(nicon
);
422 panel
->hcactionsT
[3] = WMCreateTextField(panel
->hcactionsF
);
423 WMResizeWidget(panel
->hcactionsT
[3], 180, 20);
424 WMMoveWidget(panel
->hcactionsT
[3], 50, 107);
426 WMMapSubwidgets(panel
->hcactionsF
);
430 XFreeGC(scr
->display
, gc
);
432 WMRealizeWidget(panel
->box
);
433 WMMapSubwidgets(panel
->box
);
437 static void prepareForClose(_Panel
*panel
)
440 WMScreen
*scr
= WMWidgetScreen(panel
->parent
);
442 WMReleasePixmap(panel
->icon
);
443 for (i
= 0; i
< sizeof(panel
->quarter
) / sizeof(Pixmap
); i
++)
444 XFreePixmap(scr
->display
, panel
->quarter
[i
]);
447 Panel
*InitHotCornerShortcuts(WMWidget
*parent
)
451 panel
= wmalloc(sizeof(_Panel
));
453 panel
->sectionName
= _("Hot Corner Shortcut Preferences");
454 panel
->description
= _("Choose actions to perform when you move the\n"
455 "mouse pointer to the screen corners.");
456 panel
->parent
= parent
;
458 panel
->callbacks
.createWidgets
= createPanel
;
459 panel
->callbacks
.updateDomain
= storeData
;
460 panel
->callbacks
.prepareForClose
= prepareForClose
;
462 AddSection(panel
, ICON_FILE
);