1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-03-25 22:33:31 +01:00

7 Commits

Author SHA1 Message Date
Carlos R. Mafra
d0aa2cefcd Window Maker 0.96.0 2023-08-05 08:46:23 +01:00
David Maciejak
a52d13c8b8 Fix autoconf obsolete macros
autogen.sh is reporting some warnings as below

./autogen.sh 2>&1 |grep "obsolete"
libtoolize: copying file 'm4/lt~obsolete.m4'
configure.ac:115: warning: The macro `AC_LANG_C' is obsolete.
configure.ac:115: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:134: warning: The macro `AC_LANG_C' is obsolete.
configure.ac:134: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:135: warning: The macro `AC_LANG_C' is obsolete.
configure.ac:135: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:146: warning: The macro `AC_LANG_C' is obsolete.
configure.ac:146: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:146: warning: The macro `AC_LANG_C' is obsolete.
configure.ac:146: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:373: warning: The macro `AC_LANG_C' is obsolete.
configure.ac:373: warning: The macro `AC_TRY_COMPILE' is obsolete.
configure.ac:458: warning: The macro `AC_HEADER_TIME' is obsolete.
configure.ac:681: warning: The macro `AC_TRY_LINK' is obsolete.
configure.ac:807: warning: The macro `AC_TRY_LINK' is obsolete.

As the minimum autoconf version required is v2.69,
we need to make sure to update obsolete macros as described at
https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Obsolete-Macros.html
2023-04-14 23:45:00 +01:00
David Maciejak
215b6ee2e6 Set proper motif wm hints name
Just a cosmetic change as the variable is currently not in use.
According to the Motif Toolkit API and MwmUtil.h, the last long
variable from the Motif WM Hints struct is currenlty used
for the status.
2023-04-09 10:42:52 +01:00
David Maciejak
ab45c6c6c2 Add central position feature for active window
This patch adds a new Central feature under the window menu
"Other maximization" entry.
Shortcut can be configured via WPrefs "Center active window" action.
When called the active window is centered on the screen head.
If the window height or width are bigger than the head size,
the window is resized to fit.
There are some transitions defined as below:
*from fullscreen to center
*from any corner to center
*from top half to center top half
*from bottom half to center bottom half
*from left half to center left half
*from right half to center right half

Undoing the action is done via the window menu "Unmaximize" entry
or the shortcut.
2023-03-31 09:11:38 +01:00
David Maciejak
3344f2b040 NEWS: Hot corners feature description
Add an entry in the NEWS to describe the Hot Corners feature.
2023-03-26 10:35:33 +01:00
David Maciejak
ecef2b2890 WPrefs: Hot corner preferences
Add a new "Hot Corner Shortcut Preferences" section to WPrefs
to configure the Hot Corners feature.
2023-03-26 10:35:33 +01:00
David Maciejak
802cbc0d75 Hot corners feature core
Add mouse pointer position detection to trigger the corner actions.

Screen corners can be assigned an external command to be
executed when the mouse pointer is entering those areas.

In WPrefs, "Hot Corner Shortcut Preferences" can be used
for configuration or by manually adding a "HotCorners" key
and value to "YES" in the ~/GNUstep/Defaults/WindowMaker file.

Actions are specified by the "HotCornerActions" and are defined
as a four entries list ("top left action", "top right action",
"bottom left action", "bottom right action").
A screen corner area is a cube shape defined by the "HotCornerEdge"
which is a number of pixels from 2 (by default) to 10.

To lower the risk of triggering that feature accidentally a
"HotCornerDelay" key can be used which is the time before the action
is triggered while the pointer is in one of the screen corner.
Default value is 250 ms.

Hot Corners feature is disabled by default.
2023-03-26 10:35:33 +01:00
31 changed files with 881 additions and 53 deletions

20
NEWS
View File

@@ -3,6 +3,26 @@ NEWS for veteran Window Maker users
-- 0.96.0
Hot Corners feature
--------------------------
Screen corners can be assigned an external command to be
executed when the mouse pointer is entering those areas.
In WPrefs, "Hot Corner Shortcut Preferences" can be used
for configuration or by manually adding a "HotCorners" key
and value to "YES" in the ~/GNUstep/Defaults/WindowMaker file.
Hot Corners feature is disabled by default.
Actions are specified by the "HotCornerActions" and are defined
as a four entries list ("top left action", "top right action",
"bottom left action", "bottom right action").
A screen corner area is a cube shape defined by the "HotCornerEdge"
which is a number of pixels from 2 (by default) to 10.
To lower the risk of triggering that feature accidentally a
"HotCornerDelay" key can be used which is the time before the action
is triggered while the pointer is in one of the screen corner.
Default value is 250 ms.
Screenshot capture feature
--------------------------

View File

@@ -0,0 +1,465 @@
/* HotCornerShortcuts.c - screen corners actions
*
* WPrefs - Window Maker Preferences Program
*
* Copyright (c) 2023 Window Maker Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "WPrefs.h"
typedef struct _Panel {
WMBox *box;
char *sectionName;
char *description;
CallbackRec callbacks;
WMWidget *parent;
WMPixmap *icon;
Pixmap quarter[4];
WMFrame *hcF;
WMButton *hcB;
WMFrame *hceF;
WMSlider *hceS;
WMLabel *hceL;
WMFrame *hcdescF;
WMLabel *hcdescL;
WMFrame *hcdelayF;
WMButton *hcdelayB[5];
WMTextField *hcdelayT;
WMLabel *hcdelayL;
WMLabel *icornerL;
WMFrame *hcactionsF;
WMTextField *hcactionsT[4];
char hotcornerDelaySelected;
} _Panel;
#define ICON_FILE "hotcorners"
#define DELAY_ICON "timer%i"
#define DELAY_ICON_S "timer%is"
static void edgeCallback(WMWidget * w, void *data)
{
_Panel *panel = (_Panel *) data;
char buffer[64];
int i;
/* Parameter not used, but tell the compiler that it is ok */
(void) w;
i = WMGetSliderValue(panel->hceS);
if (i == 0)
sprintf(buffer, _("OFF"));
else if (i == 1)
sprintf(buffer, _("1 pixel"));
else if (i <= 4)
/* 2-4 */
sprintf(buffer, _("%i pixels"), i);
else
/* >4 */
sprintf(buffer, _("%i pixels "), i); /* note space! */
WMSetLabelText(panel->hceL, buffer);
}
static void showData(_Panel * panel)
{
int i;
char buffer[32];
WMPropList *array;
if (!GetObjectForKey("HotCornerDelay"))
i = 250;
else
i = GetIntegerForKey("HotCornerDelay");
sprintf(buffer, "%i", i);
WMSetTextFieldText(panel->hcdelayT, buffer);
switch (i) {
case 0:
WMPerformButtonClick(panel->hcdelayB[0]);
break;
case 250:
WMPerformButtonClick(panel->hcdelayB[1]);
break;
case 500:
WMPerformButtonClick(panel->hcdelayB[2]);
break;
case 750:
WMPerformButtonClick(panel->hcdelayB[3]);
break;
case 1000:
WMPerformButtonClick(panel->hcdelayB[4]);
break;
}
i = GetIntegerForKey("HotCornerEdge");
i = i < 0 ? 2 : i;
i = i > 10 ? 10 : i;
WMSetSliderValue(panel->hceS, i);
edgeCallback(NULL, panel);
WMSetButtonSelected(panel->hcB, GetBoolForKey("HotCorners"));
array = GetObjectForKey("HotCornerActions");
if (array && (!WMIsPLArray(array) || WMGetPropListItemCount(array) != sizeof(panel->hcactionsT) / sizeof(WMTextField *))) {
wwarning(_("invalid data in option HotCornerActions."));
} else {
if (array) {
for (i = 0; i < sizeof(panel->hcactionsT) / sizeof(WMTextField *); i++)
if (strcasecmp(WMGetFromPLString(WMGetFromPLArray(array, i)), "None") != 0)
WMSetTextFieldText(panel->hcactionsT[i], WMGetFromPLString(WMGetFromPLArray(array, i)));
}
}
}
static void storeData(_Panel * panel)
{
WMPropList *list;
WMPropList *tmp;
char *str;
int i;
SetBoolForKey(WMGetButtonSelected(panel->hcB), "HotCorners");
str = WMGetTextFieldText(panel->hcdelayT);
if (sscanf(str, "%i", &i) != 1)
i = 0;
SetIntegerForKey(i, "HotCornerDelay");
free(str);
SetIntegerForKey(WMGetSliderValue(panel->hceS), "HotCornerEdge");
list = WMCreatePLArray(NULL, NULL);
for (i = 0; i < sizeof(panel->hcactionsT) / sizeof(WMTextField *); i++) {
str = WMGetTextFieldText(panel->hcactionsT[i]);
if (strlen(str) == 0)
str = "None";
tmp = WMCreatePLString(str);
WMAddToPLArray(list, tmp);
}
SetObjectForKey(list, "HotCornerActions");
}
static void pushDelayButton(WMWidget * w, void *data)
{
_Panel *panel = (_Panel *) data;
panel->hotcornerDelaySelected = 1;
if (w == panel->hcdelayB[0]) {
WMSetTextFieldText(panel->hcdelayT, "0");
} else if (w == panel->hcdelayB[1]) {
WMSetTextFieldText(panel->hcdelayT, "250");
} else if (w == panel->hcdelayB[2]) {
WMSetTextFieldText(panel->hcdelayT, "500");
} else if (w == panel->hcdelayB[3]) {
WMSetTextFieldText(panel->hcdelayT, "700");
} else if (w == panel->hcdelayB[4]) {
WMSetTextFieldText(panel->hcdelayT, "1000");
}
}
static void delayTextChanged(void *observerData, WMNotification * notification)
{
_Panel *panel = (_Panel *) observerData;
int i;
/* Parameter not used, but tell the compiler that it is ok */
(void) notification;
if (panel->hotcornerDelaySelected) {
for (i = 0; i < 5; i++) {
WMSetButtonSelected(panel->hcdelayB[i], False);
}
panel->hotcornerDelaySelected = 0;
}
}
static void createPanel(Panel * p)
{
_Panel *panel = (_Panel *) p;
int i;
char *buf1, *buf2;
WMColor *color;
WMFont *font;
char *path;
RImage *xis = NULL;
WMScreen *scr = WMWidgetScreen(panel->parent);
RContext *rc = WMScreenRContext(scr);
GC gc = XCreateGC(scr->display, WMWidgetXID(panel->parent), 0, NULL);
path = LocateImage(ICON_FILE);
if (path) {
xis = RLoadImage(rc, path, 0);
if (!xis) {
wwarning(_("could not load image file %s"), path);
}
wfree(path);
}
panel->box = WMCreateBox(panel->parent);
WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
/***************** Hot Corner lelf side frames *****************/
panel->hcF = WMCreateFrame(panel->box);
WMResizeWidget(panel->hcF, 240, 53);
WMMoveWidget(panel->hcF, 15, 17);
panel->hcB = WMCreateSwitchButton(panel->hcF);
WMResizeWidget(panel->hcB, 150, 30);
WMMoveWidget(panel->hcB, 15, 12);
WMSetButtonText(panel->hcB, _("Enable Hot Corners"));
WMMapSubwidgets(panel->hcF);
panel->hceF = WMCreateFrame(panel->box);
WMSetFrameTitle(panel->hceF, _("Hot Corner Edge"));
WMResizeWidget(panel->hceF, 240, 40);
WMMoveWidget(panel->hceF, 15, 77);
panel->hceS = WMCreateSlider(panel->hceF);
WMResizeWidget(panel->hceS, 80, 15);
WMMoveWidget(panel->hceS, 15, 18);
WMSetSliderMinValue(panel->hceS, 2);
WMSetSliderMaxValue(panel->hceS, 10);
WMSetSliderAction(panel->hceS, edgeCallback, panel);
panel->hceL = WMCreateLabel(panel->hceF);
WMResizeWidget(panel->hceL, 100, 15);
WMMoveWidget(panel->hceL, 105, 18);
WMMapSubwidgets(panel->hceF);
panel->hcdescF = WMCreateFrame(panel->box);
WMResizeWidget(panel->hcdescF, 240, 95);
WMMoveWidget(panel->hcdescF, 15, 130);
panel->hcdescL = WMCreateLabel(panel->hcdescF);
WMResizeWidget(panel->hcdescL, 200, 60);
WMMoveWidget(panel->hcdescL, 15, 10);
WMSetLabelText(panel->hcdescL,
_("Instructions:\n\n"
" - assign command to corner\n"
" - or leave it empty\n"));
WMMapSubwidgets(panel->hcdescF);
/***************** Hot Corner Action Delay *****************/
panel->hcdelayF = WMCreateFrame(panel->box);
WMResizeWidget(panel->hcdelayF, 245, 60);
WMMoveWidget(panel->hcdelayF, 265, 10);
WMSetFrameTitle(panel->hcdelayF, _("Hot Corner Delay"));
buf1 = wmalloc(strlen(DELAY_ICON) + 1);
buf2 = wmalloc(strlen(DELAY_ICON_S) + 1);
for (i = 0; i < 5; i++) {
char *path;
panel->hcdelayB[i] = WMCreateCustomButton(panel->hcdelayF, WBBStateChangeMask);
WMResizeWidget(panel->hcdelayB[i], 25, 25);
WMMoveWidget(panel->hcdelayB[i], 12 + (30 * i), 25);
WMSetButtonBordered(panel->hcdelayB[i], False);
WMSetButtonImagePosition(panel->hcdelayB[i], WIPImageOnly);
WMSetButtonAction(panel->hcdelayB[i], pushDelayButton, panel);
if (i > 0)
WMGroupButtons(panel->hcdelayB[0], panel->hcdelayB[i]);
sprintf(buf1, DELAY_ICON, i);
sprintf(buf2, DELAY_ICON_S, i);
path = LocateImage(buf1);
if (path) {
panel->icon = WMCreatePixmapFromFile(scr, path);
if (panel->icon) {
WMSetButtonImage(panel->hcdelayB[i], panel->icon);
WMReleasePixmap(panel->icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
wfree(path);
}
path = LocateImage(buf2);
if (path) {
panel->icon = WMCreatePixmapFromFile(scr, path);
if (panel->icon) {
WMSetButtonAltImage(panel->hcdelayB[i], panel->icon);
WMReleasePixmap(panel->icon);
} else {
wwarning(_("could not load icon file %s"), path);
}
wfree(path);
}
}
wfree(buf1);
wfree(buf2);
panel->hcdelayT = WMCreateTextField(panel->hcdelayF);
WMResizeWidget(panel->hcdelayT, 36, 20);
WMMoveWidget(panel->hcdelayT, 165, 28);
WMAddNotificationObserver(delayTextChanged, panel, WMTextDidChangeNotification, panel->hcdelayT);
panel->hcdelayL = WMCreateLabel(panel->hcdelayF);
WMResizeWidget(panel->hcdelayL, 36, 16);
WMMoveWidget(panel->hcdelayL, 205, 32);
WMSetLabelText(panel->hcdelayL, _("ms"));
color = WMDarkGrayColor(scr);
font = WMSystemFontOfSize(scr, 10);
WMSetLabelTextColor(panel->hcdelayL, color);
WMSetLabelFont(panel->hcdelayL, font);
WMReleaseColor(color);
WMReleaseFont(font);
WMMapSubwidgets(panel->hcdelayF);
/***************** Set Hot Corner Actions ****************/
panel->hcactionsF = WMCreateFrame(panel->box);
WMSetFrameTitle(panel->hcactionsF, _("Hot Corner Actions"));
WMResizeWidget(panel->hcactionsF, 245, 148);
WMMoveWidget(panel->hcactionsF, 265, 77);
panel->icornerL = WMCreateLabel(panel->hcactionsF);
WMResizeWidget(panel->icornerL, 24, 24);
WMMoveWidget(panel->icornerL, 10, 18);
WMSetLabelImagePosition(panel->icornerL, WIPImageOnly);
CreateImages(scr, rc, xis, ICON_FILE, &panel->icon, NULL);
if (panel->icon)
{
WMPixmap *nicon;
panel->quarter[0] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
XCopyArea(scr->display, WMGetPixmapXID(panel->icon), panel->quarter[0], gc, 0, 0, panel->icon->width/2, panel->icon->height/2, 0, 0);
nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[0], WMGetPixmapMaskXID(panel->icon),
panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
WMSetLabelImage(panel->icornerL, nicon);
WMReleasePixmap(nicon);
}
panel->hcactionsT[0] = WMCreateTextField(panel->hcactionsF);
WMResizeWidget(panel->hcactionsT[0], 180, 20);
WMMoveWidget(panel->hcactionsT[0], 50, 20);
panel->icornerL = WMCreateLabel(panel->hcactionsF);
WMResizeWidget(panel->icornerL, 24, 24);
WMMoveWidget(panel->icornerL, 10, 48);
WMSetLabelImagePosition(panel->icornerL, WIPImageOnly);
if (panel->icon)
{
WMPixmap *nicon;
panel->quarter[1] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
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);
nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[1], WMGetPixmapMaskXID(panel->icon),
panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
WMSetLabelImage(panel->icornerL, nicon);
WMReleasePixmap(nicon);
}
panel->hcactionsT[1] = WMCreateTextField(panel->hcactionsF);
WMResizeWidget(panel->hcactionsT[1], 180, 20);
WMMoveWidget(panel->hcactionsT[1], 50, 50);
panel->icornerL = WMCreateLabel(panel->hcactionsF);
WMResizeWidget(panel->icornerL, 24, 24);
WMMoveWidget(panel->icornerL, 10, 78);
WMSetLabelImagePosition(panel->icornerL, WIPImageOnly);
if (panel->icon)
{
WMPixmap *nicon;
panel->quarter[2] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
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);
nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[2], WMGetPixmapMaskXID(panel->icon),
panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
WMSetLabelImage(panel->icornerL, nicon);
WMReleasePixmap(nicon);
}
panel->hcactionsT[2] = WMCreateTextField(panel->hcactionsF);
WMResizeWidget(panel->hcactionsT[2], 180, 20);
WMMoveWidget(panel->hcactionsT[2], 50, 80);
panel->icornerL = WMCreateLabel(panel->hcactionsF);
WMResizeWidget(panel->icornerL, 24, 24);
WMMoveWidget(panel->icornerL, 10, 108);
WMSetLabelImagePosition(panel->icornerL, WIPImageOnly);
if (panel->icon)
{
WMPixmap *nicon;
panel->quarter[3] = XCreatePixmap(scr->display, WMWidgetXID(panel->parent), panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
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);
nicon = WMCreatePixmapFromXPixmaps(scr, panel->quarter[3], WMGetPixmapMaskXID(panel->icon),
panel->icon->width/2, panel->icon->height/2, WMScreenDepth(scr));
WMSetLabelImage(panel->icornerL, nicon);
WMReleasePixmap(nicon);
}
panel->hcactionsT[3] = WMCreateTextField(panel->hcactionsF);
WMResizeWidget(panel->hcactionsT[3], 180, 20);
WMMoveWidget(panel->hcactionsT[3], 50, 107);
WMMapSubwidgets(panel->hcactionsF);
if (xis)
RReleaseImage(xis);
XFreeGC(scr->display, gc);
WMRealizeWidget(panel->box);
WMMapSubwidgets(panel->box);
showData(panel);
}
static void prepareForClose(_Panel *panel)
{
int i;
WMScreen *scr = WMWidgetScreen(panel->parent);
WMReleasePixmap(panel->icon);
for (i = 0; i < sizeof(panel->quarter) / sizeof(Pixmap); i++)
XFreePixmap(scr->display, panel->quarter[i]);
}
Panel *InitHotCornerShortcuts(WMWidget *parent)
{
_Panel *panel;
panel = wmalloc(sizeof(_Panel));
panel->sectionName = _("Hot Corner Shortcut Preferences");
panel->description = _("Choose actions to perform when you move the\n"
"mouse pointer to the screen corners.");
panel->parent = parent;
panel->callbacks.createWidgets = createPanel;
panel->callbacks.updateDomain = storeData;
panel->callbacks.prepareForClose = prepareForClose;
AddSection(panel, ICON_FILE);
return panel;
}

View File

@@ -89,6 +89,7 @@ static struct keyOption {
{ "BLCMaximizeKey", N_("Maximize active window bottom left corner") },
{ "BRCMaximizeKey", N_("Maximize active window bottom right corner") },
{ "MaximusKey", N_("Tile active window") },
{ "CenterKey", N_("Center active window") },
{ "KeepOnTopKey", N_("Toggle window on top status") },
{ "KeepAtBottomKey",N_("Toggle window at bottom status") },
{ "OmnipresentKey", N_("Toggle window omnipresent status") },

View File

@@ -35,6 +35,7 @@ WPrefs_SOURCES = \
Expert.c \
Focus.c \
FontSimple.c \
HotCornerShortcuts.c \
Icons.c \
KeyboardShortcuts.c \
Menu.c \

View File

@@ -575,6 +575,7 @@ void Initialize(WMScreen * scr)
InitKeyboardSettings(WPrefs.banner);
#endif
InitKeyboardShortcuts(WPrefs.banner);
InitHotCornerShortcuts(WPrefs.banner);
InitMouseSettings(WPrefs.banner);
InitAppearance(WPrefs.banner);

View File

@@ -155,6 +155,7 @@ Panel *InitDocks(WMWidget *parent);
Panel *InitExpert(WMWidget *parent);
Panel *InitFocus(WMWidget *parent);
Panel *InitFontSimple(WMWidget *parent);
Panel *InitHotCornerShortcuts(WMWidget *parent);
Panel *InitIcons(WMWidget *parent);
Panel *InitKeyboardShortcuts(WMWidget *parent);
Panel *InitMenu(WMWidget *parent);

View File

@@ -14,6 +14,7 @@ POTFILES = \
$(top_srcdir)/WPrefs.app/Expert.c \
$(top_srcdir)/WPrefs.app/Focus.c \
$(top_srcdir)/WPrefs.app/FontSimple.c \
$(top_srcdir)/WPrefs.app/HotCornerShortcuts.c \
$(top_srcdir)/WPrefs.app/Icons.c \
$(top_srcdir)/WPrefs.app/KeyboardShortcuts.c \
$(top_srcdir)/WPrefs.app/Menu.c \

View File

@@ -15,6 +15,7 @@ dist_tiffdata_DATA = \
ergonomic.tiff \
expert.tiff \
fonts.tiff \
hotcorners.tiff \
iconprefs.tiff \
keyboard.tiff \
keyboardprefs.tiff \

Binary file not shown.

View File

@@ -15,6 +15,7 @@ dist_xpmdata_DATA = \
ergonomic.xpm \
expert.xpm \
fonts.xpm \
hotcorners.xpm \
iconprefs.xpm \
keyboard.xpm \
keyboardprefs.xpm \

View File

@@ -0,0 +1,137 @@
/* XPM */
static char * hotcorners_xpm[] = {
"48 48 86 1",
" c #2C2C2C",
". c #FEFEFE",
"+ c #505075",
"@ c #4E4E74",
"# c #515176",
"$ c #4B4B72",
"% c #494971",
"& c #515175",
"* c #4F4F74",
"= c #4C4C73",
"- c #696984",
"; c #545477",
"> c #5E5E7D",
", c #676783",
"' c #58587A",
") c #5B5B7C",
"! c #B1B1BB",
"~ c #A5A5B1",
"{ c #A1A1AE",
"] c #AEAEB9",
"^ c #79798F",
"/ c #5C5C7C",
"( c #D5D5DA",
"_ c #E6E6E9",
": c #E8E8EB",
"< c #EDEDEF",
"[ c #E7E7EA",
"} c #FDFDFD",
"| c #FFFFFF",
"1 c #EBEBEC",
"2 c #7F7F93",
"3 c #484871",
"4 c #7B7B85",
"5 c #EFEFEF",
"6 c #A6A6A6",
"7 c #292959",
"8 c #464670",
"9 c #8C8C96",
"0 c #F4F4F4",
"a c #F5F5F6",
"b c #F2F2F2",
"c c #9797A6",
"d c #474770",
"e c #4D4D73",
"f c #9393A3",
"g c #F4F4F5",
"h c #F3F3F3",
"i c #EBEBEE",
"j c #6D6D87",
"k c #9D9DAB",
"l c #F9F9F9",
"m c #F1F1F1",
"n c #A5A5A5",
"o c #EAEAEA",
"p c #6A6A86",
"q c #D3D3D6",
"r c #717171",
"s c #848484",
"t c #9F9FA3",
"u c #47476F",
"v c #323256",
"w c #9B9B9A",
"x c #888889",
"y c #000012",
"z c #6B6B6D",
"A c #757587",
"B c #46466D",
"C c #3B3B47",
"D c #2E2E50",
"E c #242447",
"F c #838383",
"G c #919191",
"H c #202041",
"I c #4F4F73",
"J c #4E4E72",
"K c #232343",
"L c #4F4F4F",
"M c #252548",
"N c #505074",
"O c #3A3A57",
"P c #404060",
"Q c #505076",
"R c #49496B",
"S c #31314E",
"T c #2F2F49",
"U c #434362",
" .",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++@#$%&*=+++++++++++++++++++++++++++%-;>,')@++.",
" ++)!~{]]^@++++++++++++++++++++++++++/(_:<[!#++.",
" ++'[.}|12*++++++++++++++++++++++++++345||.~$++.",
" ++,<||}67+++++++++++++++++++++++++++890||}{%++a",
" ++>:|||bcd+++++++++++++++++++++++++efg||}|]&++.",
" ++;_5h||ij+++++++++++++++++++++++++@kl|mno]*++.",
" ++pqrshltu++++++++++++++++++++++++++vwoxyzAe++.",
" ++BCDEFGHI++++++++++++++++++++++++++JKLMNOP+++.",
" ++QR+*STJ++++++++++++++++++++++++++++JU*++++++.",
" +++++++*++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++QR+*STJ++++++++++++++++++++++++++++JTS*+RQ++.",
" ++BCDEFGHI++++++++++++++++++++++++++IHGFEDCB++.",
" ++pqrshltu++++++++++++++++++++++++++utlhsrqp++.",
" ++;_5h||ij++++++++++++++++++++++++++ji||h5_;++.",
" ++>:|||bcd++++++++++++++++++++++++++dcb|||:>++.",
" ++,<||}67++++++++++++++++++++++++++++76}||<,++.",
" ++'[.}|12*++++++++++++++++++++++++++*21|}.['++.",
" ++)!~{]]^@++++++++++++++++++++++++++@^]]{~!)++.",
" ++@#$%&*=++++++++++++++++++++++++++++=*&%$#@++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
" ++++++++++++++++++++++++++++++++++++++++++++++.",
"................................................"};

View File

@@ -34,7 +34,7 @@ AC_PREREQ([2.69])
dnl Configuration for Autoconf and Automake
dnl =======================================
AC_INIT([WindowMaker],[0.95.9],[wmaker-dev@googlegroups.com],[WindowMaker],[http://www.windowmaker.org/])
AC_INIT([WindowMaker],[0.96.0],[wmaker-dev@googlegroups.com],[WindowMaker],[http://www.windowmaker.org/])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
@@ -455,7 +455,6 @@ AC_CHECK_HEADERS([syslog.h], [AC_DEFINE([HAVE_SYSLOG], [1], [Check for syslog])]
dnl Checks for header files
dnl =======================
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS(fcntl.h limits.h sys/ioctl.h libintl.h poll.h malloc.h ctype.h \
string.h strings.h)

View File

@@ -80,14 +80,14 @@ AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_$2])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
AC_LANG(C)
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC
"-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
@@ -116,14 +116,14 @@ AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$2])dnl
AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_LANG(C++)
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC
"-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
@@ -151,14 +151,14 @@ AS_VAR_PUSHDEF([VAR],[ax_cv_cflags_gcc_option_$1])dnl
AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_C
AC_LANG(C)
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC
"-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"
@@ -187,14 +187,14 @@ AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_gcc_option_$1])dnl
AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)],
VAR,[VAR="no, unknown"
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_LANG(C++)
ac_save_[]FLAGS="$[]FLAGS"
for ac_arg dnl
in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC
"-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC
#
do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
AC_TRY_COMPILE([],[return 0;],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[return 0;])],
[VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
done
FLAGS="$ac_save_[]FLAGS"

View File

@@ -47,14 +47,15 @@ AC_DEFUN([WM_CHECK_XFT_VERSION],
AC_CACHE_CHECK([whether libXft is at least version $1], [ac_cv_lib_xft_version_ok],
[CPPFLAGS_save="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $XFT_CFLAGS $inc_search_path"
AC_TRY_LINK([
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
], [
#if !defined(XFT_VERSION) || XFT_VERSION < ]XFT_REQUIRED_VERSION[
#error libXft on this system is too old. Consider upgrading to at least $1
#endif
], [ac_cv_lib_xft_version_ok=yes], [ac_cv_lib_xft_version_ok=no])
])], [ac_cv_lib_xft_version_ok=yes], [ac_cv_lib_xft_version_ok=no])
CPPFLAGS="$CPPFLAGS_save"])
m4_undefine([XFT_REQUIRED_VERSION])dnl
AS_IF([test "x$ac_cv_lib_xft_version_ok" != "xyes"], [$3], [$2])dnl

View File

@@ -198,9 +198,9 @@ AC_DEFUN_ONCE([WM_IMGFMT_CHECK_WEBP],
dnl a symbol without first using the header to handle it
wm_save_LIBS="$LIBS"
LIBS="$LIBS -lwebp"
AC_TRY_LINK(
[@%:@include <webp/decode.h>],
[WebPGetFeatures(NULL, 1024, NULL);],
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([@%:@include <webp/decode.h>],
[WebPGetFeatures(NULL, 1024, NULL);])],
[wm_cv_imgfmt_webp="-lwebp"])
LIBS="$wm_save_LIBS"
AS_IF([test "x$enable_webp$wm_cv_imgfmt_webp" = "xyesno"],

View File

@@ -474,6 +474,11 @@ extern struct WPreferences {
char show_clip_title;
char hot_corners; /* let corners execute actions */
int hot_corner_delay; /* Delay after which the hot corner is triggered */
int hot_corner_edge; /* Hot corner edge size */
char *hot_corner_actions[4]; /* Action of each corner */
struct {
#ifdef USE_ICCCM_WMREPLACE
unsigned int replace:1; /* replace existing window manager */

View File

@@ -404,7 +404,7 @@ void wMaximizeWindow(WWindow *wwin, int directions, int head)
usableArea = wGetUsableAreaForHead(scr, head, &totalArea, True);
/* Only save directions, not kbd or xinerama hints */
directions &= (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS);
directions &= (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS | MAX_CENTRAL);
if (WFLAGP(wwin, full_maximize))
usableArea = totalArea;
@@ -431,12 +431,31 @@ void wMaximizeWindow(WWindow *wwin, int directions, int head)
wwin->maximus_y = new_y;
wwin->flags.old_maximized |= MAX_MAXIMUS;
} else {
/* center the window if can fit, if not sticking it to the screen edges */
if (directions & MAX_CENTRAL) {
if (wwin->frame->core->height > (usableArea.y2 - usableArea.y1)) {
new_y = usableArea.y1;
new_height = usableArea.y2 - usableArea.y1 - adj_size;
} else {
new_height = (wwin->old_geometry.height) ? wwin->old_geometry.height : wwin->frame->core->height;
new_height += wwin->frame->top_width + wwin->frame->bottom_width;
new_y = half_scr_height - new_height / 2;
}
if (wwin->frame->core->width > (usableArea.x2 - usableArea.x1)) {
new_x = usableArea.x1;
new_width = usableArea.x2 - usableArea.x1 - adj_size;
}
else {
new_width = (wwin->old_geometry.width) ? wwin->old_geometry.width : wwin->frame->core->width;
new_x = half_scr_width - new_width / 2;
}
}
/* set default values if no option set then */
if (!(directions & (MAX_HORIZONTAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS))) {
if (!(directions & (MAX_HORIZONTAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS | MAX_CENTRAL))) {
new_width = (wwin->old_geometry.width) ? wwin->old_geometry.width : wwin->frame->core->width;
new_x = (wwin->old_geometry.x) ? wwin->old_geometry.x : wwin->frame_x;
}
if (!(directions & (MAX_VERTICAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS))) {
if (!(directions & (MAX_VERTICAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS| MAX_CENTRAL))) {
new_height = (wwin->old_geometry.height) ? wwin->old_geometry.height : wwin->frame->core->height;
new_y = (wwin->old_geometry.y) ? wwin->old_geometry.y : wwin->frame_y;
}
@@ -445,17 +464,26 @@ void wMaximizeWindow(WWindow *wwin, int directions, int head)
if (directions & MAX_LEFTHALF) {
new_width = half_scr_width - adj_size;
new_x = usableArea.x1;
if (directions & MAX_CENTRAL) {
new_y = half_scr_height - wwin->old_geometry.height / 2;
}
} else if (directions & MAX_RIGHTHALF) {
new_width = half_scr_width - adj_size;
new_x = usableArea.x1 + half_scr_width;
if (directions & MAX_CENTRAL)
new_y = half_scr_height - wwin->old_geometry.height / 2;
}
/* top|bottom position */
if (directions & MAX_TOPHALF) {
new_height = half_scr_height - adj_size;
new_y = usableArea.y1;
if (directions & MAX_CENTRAL)
new_x = half_scr_width - wwin->old_geometry.width / 2;
} else if (directions & MAX_BOTTOMHALF) {
new_height = half_scr_height - adj_size;
new_y = usableArea.y1 + half_scr_height;
if (directions & MAX_CENTRAL)
new_x = half_scr_width - wwin->old_geometry.width / 2;
}
/* vertical|horizontal position */
@@ -494,7 +522,7 @@ void wMaximizeWindow(WWindow *wwin, int directions, int head)
void handleMaximize(WWindow *wwin, int directions)
{
int current = wwin->flags.maximized;
int requested = directions & (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS);
int requested = directions & (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS | MAX_CENTRAL);
int effective = requested ^ current;
int flags = directions & ~requested;
int head = wGetHeadForWindow(wwin);
@@ -625,11 +653,24 @@ void handleMaximize(WWindow *wwin, int directions)
head);
else {
if ((requested == (MAX_HORIZONTAL | MAX_VERTICAL)) ||
(requested == MAX_MAXIMUS))
effective = requested;
else {
if (requested & MAX_LEFTHALF) {
if (requested & MAX_CENTRAL) {
effective |= MAX_CENTRAL;
if (current & (MAX_HORIZONTAL | MAX_VERTICAL))
effective &= ~(MAX_HORIZONTAL | MAX_VERTICAL);
else if (current & MAX_TOPHALF && current & MAX_LEFTHALF)
effective &= ~(MAX_TOPHALF | MAX_LEFTHALF);
else if (current & MAX_TOPHALF && current & MAX_RIGHTHALF)
effective &= ~(MAX_TOPHALF | MAX_RIGHTHALF);
else if (current & MAX_BOTTOMHALF && current & MAX_LEFTHALF)
effective &= ~(MAX_BOTTOMHALF | MAX_LEFTHALF);
else if (current & MAX_BOTTOMHALF && current & MAX_RIGHTHALF)
effective &= ~(MAX_BOTTOMHALF | MAX_RIGHTHALF);
} else if (requested & MAX_LEFTHALF) {
if (!(requested & (MAX_TOPHALF | MAX_BOTTOMHALF)))
effective |= MAX_VERTICAL;
else

View File

@@ -30,8 +30,9 @@
#define MAX_TOPHALF (1 << 4)
#define MAX_BOTTOMHALF (1 << 5)
#define MAX_MAXIMUS (1 << 6)
#define MAX_IGNORE_XINERAMA (1 << 7)
#define MAX_KEYBOARD (1 << 8)
#define MAX_CENTRAL (1 << 7)
#define MAX_IGNORE_XINERAMA (1 << 8)
#define MAX_KEYBOARD (1 << 9)
#define SAVE_GEOMETRY_X (1 << 0)
#define SAVE_GEOMETRY_Y (1 << 1)

View File

@@ -240,9 +240,9 @@ void wClientConfigure(WWindow * wwin, XConfigureRequestEvent * xcre)
return;
if (nwidth != wwin->old_geometry.width)
wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS);
wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS | MAX_CENTRAL);
if (nheight != wwin->old_geometry.height)
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS);
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS | MAX_CENTRAL);
wWindowConstrainSize(wwin, (unsigned int *)&nwidth, (unsigned int *)&nheight);
wWindowConfigure(wwin, nx, ny, nwidth, nheight);

View File

@@ -36,6 +36,10 @@ static unsigned char MENU_SNAP_H_INDICATOR_XBM_DATA[] = {
0xff, 0x03, 0x01, 0x02, 0xff, 0x03, 0xff, 0x03, 0xff, 0x03, 0x01, 0x02,
0x01, 0x02, 0x01, 0x02, 0xff, 0x03 };
static unsigned char MENU_CENTRAL_INDICATOR_XBM_DATA[] = {
0xff, 0x03, 0x01, 0x02, 0x79, 0x02, 0x79, 0x02, 0x79, 0x02, 0x79, 0x02,
0x79, 0x02, 0x01, 0x02, 0xff, 0x03 };
static unsigned char MENU_SNAP_RH_INDICATOR_XBM_DATA[] = {
0xff, 0x03, 0x01, 0x02, 0xe1, 0x02, 0xe1, 0x02, 0xe1, 0x02, 0xe1, 0x02,
0xe1, 0x02, 0x01, 0x02, 0xff, 0x03 };

View File

@@ -151,6 +151,7 @@ static WDECallbackUpdate setSwPOptions;
static WDECallbackUpdate updateUsableArea;
static WDECallbackUpdate setModifierKeyLabels;
static WDECallbackUpdate setHotCornerActions;
static WDECallbackConvert getCursor;
static WDECallbackUpdate setCursor;
@@ -525,6 +526,14 @@ WDefaultEntry optionList[] = {
{"KeepDockOnPrimaryHead", "NO", NULL,
&wPreferences.keep_dock_on_primary_head, getBool, updateDock,
NULL, NULL},
{"HotCorners", "NO", NULL,
&wPreferences.hot_corners, getBool, NULL, NULL, NULL},
{"HotCornerDelay", "250", (void *)&wPreferences.hot_corner_delay,
&wPreferences.hot_corner_delay, getInt, NULL, NULL, NULL},
{"HotCornerEdge", "2", (void *)&wPreferences.hot_corner_edge,
&wPreferences.hot_corner_edge, getInt, NULL, NULL, NULL},
{"HotCornerActions", "(\"None\", \"None\", \"None\", \"None\")", &wPreferences,
NULL, getPropList, setHotCornerActions, NULL, NULL},
/* style options */
@@ -672,6 +681,8 @@ WDefaultEntry optionList[] = {
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"MaximusKey", "None", (void*)WKBD_MAXIMUS,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"CenterKey", "None", (void *)WKBD_CENTRAL,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"KeepOnTopKey", "None", (void *)WKBD_KEEP_ON_TOP,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"KeepAtBottomKey", "None", (void *)WKBD_KEEP_AT_BOTTOM,
@@ -3461,6 +3472,43 @@ static int setModifierKeyLabels(WScreen * scr, WDefaultEntry * entry, void *tdat
return 0;
}
static int setHotCornerActions(WScreen * scr, WDefaultEntry * entry, void *tdata, void *foo)
{
WMPropList *array = tdata;
int i;
struct WPreferences *prefs = foo;
if (!WMIsPLArray(array) || WMGetPropListItemCount(array) != 4) {
wwarning(_("Value for option \"%s\" must be an array of 4 strings"), entry->key);
WMReleasePropList(array);
return 0;
}
DestroyWindowMenu(scr);
for (i = 0; i < 4; i++) {
if (prefs->hot_corner_actions[i])
wfree(prefs->hot_corner_actions[i]);
if (WMIsPLString(WMGetFromPLArray(array, i))) {
const char *val;
val = WMGetFromPLString(WMGetFromPLArray(array, i));
if (strcasecmp(val, "NONE") != 0)
prefs->hot_corner_actions[i] = wstrdup(val);
else
prefs->hot_corner_actions[i] = NULL;
} else {
wwarning(_("Invalid argument for option \"%s\" item %d"), entry->key, i);
prefs->hot_corner_actions[i] = NULL;
}
}
WMReleasePropList(array);
return 0;
}
static int setDoubleClick(WScreen *scr, WDefaultEntry *entry, void *tdata, void *foo)
{
int *value = tdata;

View File

@@ -1515,6 +1515,14 @@ static void handleKeyPress(XEvent * event)
movePointerToWindowCenter(wwin);
}
break;
case WKBD_CENTRAL:
if (ISMAPPED(wwin) && ISFOCUSED(wwin) && IS_RESIZABLE(wwin)) {
CloseWindowMenu(scr);
handleMaximize(wwin, MAX_CENTRAL | MAX_KEYBOARD);
movePointerToWindowCenter(wwin);
}
break;
case WKBD_LHMAXIMIZE:
if (ISMAPPED(wwin) && ISFOCUSED(wwin) && IS_RESIZABLE(wwin)) {
CloseWindowMenu(scr);
@@ -1928,27 +1936,104 @@ static void handleKeyPress(XEvent * event)
}
}
static void handleMotionNotify(XEvent * event)
{
WScreen *scr = wScreenForRootWindow(event->xmotion.root);
#define CORNER_NONE 0
#define CORNER_TOPLEFT 1
#define CORNER_TOPRIGHT 2
#define CORNER_BOTTOMLEFT 3
#define CORNER_BOTTOMRIGHT 4
if (wPreferences.scrollable_menus) {
static int get_corner(WMRect rect, WMPoint p)
{
if (p.x <= (rect.pos.x + wPreferences.hot_corner_edge) && p.y <= (rect.pos.y + wPreferences.hot_corner_edge))
return CORNER_TOPLEFT;
if (p.x >= (rect.pos.x + rect.size.width - wPreferences.hot_corner_edge) && p.y <= (rect.pos.y + wPreferences.hot_corner_edge))
return CORNER_TOPRIGHT;
if (p.x <= (rect.pos.x + wPreferences.hot_corner_edge) && p.y >= (rect.pos.y + rect.size.height - wPreferences.hot_corner_edge))
return CORNER_BOTTOMLEFT;
if (p.x >= (rect.pos.x + rect.size.width - wPreferences.hot_corner_edge) && p.y >= (rect.pos.y + rect.size.height - wPreferences.hot_corner_edge))
return CORNER_BOTTOMRIGHT;
return CORNER_NONE;
}
static void hotCornerDelay(void *data)
{
WScreen *scr = (WScreen *) data;
if (scr->flags.in_hot_corner && wPreferences.hot_corner_actions[scr->flags.in_hot_corner - 1])
ExecuteShellCommand(scr, wPreferences.hot_corner_actions[scr->flags.in_hot_corner - 1]);
WMDeleteTimerHandler(scr->hot_corner_timer);
scr->hot_corner_timer = NULL;
}
static void handleMotionNotify(XEvent *event)
{
if (wPreferences.scrollable_menus || wPreferences.hot_corners) {
WScreen *scr = wScreenForRootWindow(event->xmotion.root);
WMPoint p = wmkpoint(event->xmotion.x_root, event->xmotion.y_root);
WMRect rect = wGetRectForHead(scr, wGetHeadForPoint(scr, p));
if (scr->flags.jump_back_pending ||
p.x <= (rect.pos.x + 1) ||
p.x >= (rect.pos.x + rect.size.width - 2) ||
p.y <= (rect.pos.y + 1) || p.y >= (rect.pos.y + rect.size.height - 2)) {
WMenu *menu;
if (wPreferences.hot_corners) {
if (!scr->flags.in_hot_corner) {
scr->flags.in_hot_corner = get_corner(rect, p);
if (scr->flags.in_hot_corner && !scr->hot_corner_timer)
scr->hot_corner_timer = WMAddTimerHandler(wPreferences.hot_corner_delay, hotCornerDelay, scr);
} else {
int out_hot_corner = 0;
menu = wMenuUnderPointer(scr);
if (menu != NULL)
wMenuScroll(menu);
switch (scr->flags.in_hot_corner) {
case CORNER_TOPLEFT:
if ((p.x > (rect.pos.x + wPreferences.hot_corner_edge)) ||
(p.y > (rect.pos.y + wPreferences.hot_corner_edge)))
out_hot_corner = 1;
break;
case CORNER_TOPRIGHT:
if ((p.x < (rect.pos.x + rect.size.width - wPreferences.hot_corner_edge)) ||
(p.y > (rect.pos.y + wPreferences.hot_corner_edge)))
out_hot_corner = 1;
break;
case CORNER_BOTTOMLEFT:
if ((p.x > (rect.pos.x + wPreferences.hot_corner_edge)) ||
(p.y < (rect.pos.y + rect.size.height - wPreferences.hot_corner_edge)))
out_hot_corner = 1;
break;
case CORNER_BOTTOMRIGHT:
if ((p.x < (rect.pos.x + rect.size.width - wPreferences.hot_corner_edge)) ||
(p.y < (rect.pos.y + rect.size.height - wPreferences.hot_corner_edge)))
out_hot_corner = 1;
break;
}
if (out_hot_corner) {
scr->flags.in_hot_corner = CORNER_NONE;
if (scr->hot_corner_timer) {
WMDeleteTimerHandler(scr->hot_corner_timer);
scr->hot_corner_timer = NULL;
}
}
}
}
if (wPreferences.scrollable_menus) {
if (scr->flags.jump_back_pending ||
p.x <= (rect.pos.x + 1) ||
p.x >= (rect.pos.x + rect.size.width - 2) ||
p.y <= (rect.pos.y + 1) || p.y >= (rect.pos.y + rect.size.height - 2)) {
WMenu *menu;
menu = wMenuUnderPointer(scr);
if (menu != NULL)
wMenuScroll(menu);
}
}
}
}
#undef CORNER_NONE
#undef CORNER_TOPLEFT
#undef CORNER_TOPRIGHT
#undef CORNER_BOTTOMLEFT
#undef CORNER_BOTTOMRIGHT
static void handleVisibilityNotify(XEvent * event)
{
WWindow *wwin;

View File

@@ -76,6 +76,7 @@ enum {
WKBD_FOCUSPREV,
WKBD_GROUPNEXT,
WKBD_GROUPPREV,
WKBD_CENTRAL,
/* window, menu */
WKBD_CLOSE,

View File

@@ -743,10 +743,13 @@ static void paintEntry(WMenu * menu, int index, int selected)
indicator = scr->menu_shade_indicator;
break;
case MI_SNAP_V:
indicator = scr->menu_snap_vertically_indicator;
indicator = scr->menu_snap_vertical_indicator;
break;
case MI_SNAP_H:
indicator = scr->menu_snap_horizontally_indicator;
indicator = scr->menu_snap_horizontal_indicator;
break;
case MI_CENTRAL:
indicator = scr->menu_central_indicator;
break;
case MI_SNAP_RH:
indicator = scr->menu_snap_rh_indicator;

View File

@@ -40,6 +40,7 @@
#define MI_SNAP_BL 14
#define MI_SNAP_BR 15
#define MI_SNAP_TILED 16
#define MI_CENTRAL 17
typedef struct WMenuEntry {
int order;

View File

@@ -62,7 +62,7 @@ typedef struct {
long functions;
long decorations;
long inputMode;
long unknown;
long status;
} MWMHints;
static Atom _XA_MOTIF_WM_HINTS;
@@ -180,7 +180,7 @@ static int getMWMHints(Window window, MWMHints *mwmhints)
mwmhints->decorations = data[2];
mwmhints->inputMode = data[3];
if (count > 5)
mwmhints->unknown = data[4];
mwmhints->status = data[4];
}
XFree(data);

View File

@@ -1665,10 +1665,10 @@ int wKeyboardMoveResizeWindow(WWindow * wwin)
}
} else {
if (ww != original_w)
wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS);
wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS | MAX_CENTRAL);
if (wh != original_h)
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS);
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS | MAX_CENTRAL);
wWindowConfigure(wwin, src_x + off_x, src_y + off_y, ww, wh - vert_border);
wWindowSynthConfigureNotify(wwin);
@@ -2283,10 +2283,10 @@ void wMouseResizeWindow(WWindow * wwin, XEvent * ev)
XUngrabServer(dpy);
if (fw != original_fw)
wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS);
wwin->flags.maximized &= ~(MAX_HORIZONTAL | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS | MAX_CENTRAL);
if (fh != original_fh)
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS);
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS | MAX_CENTRAL);
wWindowConfigure(wwin, fx, fy, fw, fh - vert_border);
wWindowSynthConfigureNotify(wwin);

View File

@@ -498,8 +498,9 @@ static void createPixmaps(WScreen * scr)
LOADPIXMAPINDICATOR(MENU_HIDE_INDICATOR_XBM_DATA, MENU_HIDE_INDICATOR_XBM_SIZE, menu_hide_indicator)
LOADPIXMAPINDICATOR(MENU_SHADE_INDICATOR_XBM_DATA, MENU_SHADE_INDICATOR_XBM_SIZE, menu_shade_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_V_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_vertically_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_H_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_horizontally_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_V_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_vertical_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_H_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_horizontal_indicator)
LOADPIXMAPINDICATOR(MENU_CENTRAL_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_central_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_RH_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_rh_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_LH_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_lh_indicator)
LOADPIXMAPINDICATOR(MENU_SNAP_TH_INDICATOR_XBM_DATA, MENU_SNAP_INDICATOR_W_XBM_SIZE, menu_snap_th_indicator)

View File

@@ -214,8 +214,8 @@ typedef struct _WScreen {
struct WPixmap *menu_mini_indicator; /* for miniwindow */
struct WPixmap *menu_hide_indicator; /* for hidden window */
struct WPixmap *menu_shade_indicator; /* for shaded window */
struct WPixmap *menu_snap_vertically_indicator; /* for vertically snap window */
struct WPixmap *menu_snap_horizontally_indicator; /* for horizontally snap window */
struct WPixmap *menu_snap_vertical_indicator; /* for vertical snap window */
struct WPixmap *menu_snap_horizontal_indicator; /* for horizontal snap window */
struct WPixmap *menu_snap_rh_indicator; /* for righ half snap window */
struct WPixmap *menu_snap_lh_indicator; /* for left half snap window */
struct WPixmap *menu_snap_th_indicator; /* for top half snap window */
@@ -225,6 +225,7 @@ typedef struct _WScreen {
struct WPixmap *menu_snap_bl_indicator; /* for bottom left snap window */
struct WPixmap *menu_snap_br_indicator; /* for bottom right snap window */
struct WPixmap *menu_snap_tiled_indicator; /* for tiled window */
struct WPixmap *menu_central_indicator; /* for central window */
int app_menu_x, app_menu_y; /* position for application menus */
@@ -295,6 +296,8 @@ typedef struct _WScreen {
WMHandlerID *autoRaiseTimer;
Window autoRaiseWindow; /* window that is scheduled to be
* raised */
/* for hot-corners delay */
WMHandlerID *hot_corner_timer;
/* for window shortcuts */
WMArray *shortcutWindows[MAX_WINDOW_SHORTCUTS];
@@ -323,6 +326,7 @@ typedef struct _WScreen {
unsigned int doing_alt_tab:1;
unsigned int jump_back_pending:1;
unsigned int ignore_focus_events:1;
unsigned int in_hot_corner:3;
} flags;
} WScreen;

View File

@@ -251,8 +251,8 @@ typedef struct WWindow {
unsigned int miniaturized:1;
unsigned int hidden:1;
unsigned int shaded:1;
unsigned int maximized:7;
unsigned int old_maximized:7;
unsigned int maximized:10;
unsigned int old_maximized:10;
unsigned int fullscreen:1;
long fullscreen_monitors[4];
unsigned int omnipresent:1;

View File

@@ -124,8 +124,9 @@ static const struct {
unsigned int shortcut_idx;
int maxim_direction;
} menu_maximize_entries[] = {
{ MI_SNAP_V, N_("Vertically"), WKBD_VMAXIMIZE, MAX_VERTICAL },
{ MI_SNAP_H, N_("Horizontally"), WKBD_HMAXIMIZE, MAX_HORIZONTAL },
{ MI_SNAP_V, N_("Vertical"), WKBD_VMAXIMIZE, MAX_VERTICAL },
{ MI_SNAP_H, N_("Horizontal"), WKBD_HMAXIMIZE, MAX_HORIZONTAL },
{ MI_CENTRAL, N_("Central"), WKBD_CENTRAL, MAX_CENTRAL },
{ MI_SNAP_LH, N_("Left half"), WKBD_LHMAXIMIZE, MAX_VERTICAL | MAX_LEFTHALF },
{ MI_SNAP_RH, N_("Right half"), WKBD_RHMAXIMIZE, MAX_VERTICAL | MAX_RIGHTHALF },
{ MI_SNAP_TH, N_("Top half"), WKBD_THMAXIMIZE, MAX_HORIZONTAL | MAX_TOPHALF },
@@ -181,7 +182,7 @@ static void updateUnmaximizeShortcut(WMenuEntry * entry, int flags)
{
int key;
switch (flags & (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS)) {
switch (flags & (MAX_HORIZONTAL | MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_TOPHALF | MAX_BOTTOMHALF | MAX_MAXIMUS | MAX_CENTRAL)) {
case MAX_HORIZONTAL:
key = WKBD_HMAXIMIZE;
break;
@@ -190,6 +191,10 @@ static void updateUnmaximizeShortcut(WMenuEntry * entry, int flags)
key = WKBD_VMAXIMIZE;
break;
case MAX_CENTRAL:
key = WKBD_CENTRAL;
break;
case MAX_LEFTHALF | MAX_VERTICAL:
key = WKBD_LHMAXIMIZE;
break;