1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-07-10 04:36:36 +02:00

Compare commits

..

36 Commits

Author SHA1 Message Date
David 7b317a5fba wmiv: use W_KeycodeToKeysym instead of XkbKeycodeToKeysym
This patch replaces XkbKeycodeToKeysym in wmiv by our
own function W_KeycodeToKeysym.
2023-02-28 03:33:21 +00:00
David Maciejak 9f8dc6f5dc Use W_KeycodeToKeysym instead of XkbKeycodeToKeysym
This patch replaces XkbKeycodeToKeysym by our
own function W_KeycodeToKeysym.
2023-02-27 23:05:27 +00:00
David Maciejak bc56db0776 WPrefs: use W_KeycodeToKeysym instead of XkbKeycodeToKeysym
This patch replaces XKeycodeToKeysym and XkbKeycodeToKeysym
in WPrefs by our own function W_KeycodeToKeysym.
2023-02-27 23:05:27 +00:00
David Maciejak 15d06ff064 WINGs: Add W_KeycodeToKeysym to replace XKeycodeToKeysym/XkbKeycodeToKeysym calls
XKeycodeToKeysym was deprecated some time ago and we replaced
those function calls to XkbKeycodeToKeysym.
Usage of XkbKeycodeToKeysym is not the best as it appears
the XKEYBOARD can be disabled via xorg.conf (at least on Linux).
So just replacing XKeycodeToKeysym() with XkbKeycodeToKeysym()
could cause run-time errors on top of the compilation warning
we may have.
Better fix is to address the problem without introducing a
dependency on XKEYBOARD. W_KeycodeToKeysym is the equivalent
code for XKeycodeToKeysym/XkbKeycodeToKeysym using
XGetKeyboardMapping instead.

As a new function is added to the library WINGs library version
is bumped.
2023-02-27 22:37:44 +00:00
David Maciejak 2dd98666f1 Store window maximize state as hex value
As the maximize state is defined as a bit-field internally.
Better to store the flag in the WMSTATE file as hex value.
2023-02-27 22:37:44 +00:00
David Maciejak d1a7db8aea Compile by default with POSIX 7 revision
Compile by default with POSIX-2008 standard for Linux and FreeBSD.
2023-02-27 22:37:44 +00:00
David Maciejak 64a8ecb390 Code cleaning: removing trailing space
The patch is removing trailing space(s) before
the semicolon ending line. .c and .h files were checked.
2023-02-27 22:37:44 +00:00
David Maciejak a9e336256b Doc: add disable-res description 2023-02-26 11:02:46 +00:00
David Maciejak e9b20b51e9 WPrefs: check if captured keyboard shortcut is not in use
Make sure the captured keyboard shortcut is not already in use
by another action, if it's the case an error popup is shown and
the key is not kept.
2023-02-25 13:31:42 +00:00
David Maciejak 1d8b38b6e0 Fix compiler warnings from texture.c v2
The patch fixes those 2 warnings below from texture.c.
It reverts the previous v1 patch and fixes the compiler warning
by updating the texture.h wTextureMakeIGradient header instead.

texture.c:205:81: warning: argument 3 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  205 | WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor colors1[2],
      |                                                                    ~~~~~~~~~~~~~^~~~~~~~~~
In file included from texture.c:33:
texture.h:165:53: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |                                                     ^~~~~~~~~~~~~~
texture.c:206:67: warning: argument 5 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  206 |                                      int thickness2, const RColor colors2[2])
      |                                                      ~~~~~~~~~~~~~^~~~~~~~~~
texture.h:165:74: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |
2023-02-25 13:31:42 +00:00
David Maciejak 82ad19d420 Fix compiler warnings from texture.c
The patch fixes those 2 warnings below from texture.c

texture.c:205:81: warning: argument 3 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  205 | WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor colors1[2],
      |                                                                    ~~~~~~~~~~~~~^~~~~~~~~~
In file included from texture.c:33:
texture.h:165:53: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |                                                     ^~~~~~~~~~~~~~
texture.c:206:67: warning: argument 5 of type 'const RColor[2]' with mismatched bound [-Warray-parameter=]
  206 |                                      int thickness2, const RColor colors2[2])
      |                                                      ~~~~~~~~~~~~~^~~~~~~~~~
texture.h:165:74: note: previously declared as 'const RColor[]'
  165 | WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
      |
2023-02-24 12:19:38 +00:00
David Maciejak 492b22d975 Fix compiler warning from menu.c
The patch fixes the compiler warning below

menu.c: In function 'restoreMenuRecurs':
menu.c:2450:47: warning: '%s' directive output may be truncated writing up to 510 bytes into a region of size between 509 and 1019 [-Wformat-truncation=]
 2450 |         snprintf(buffer, sizeof(buffer), "%s\\%s", path, menu->frame->title);
      |                                               ^~

The code is taking care of checking properly the string passed to the buffer,
so there is no issue, the change is just to make the compiler happy.
2023-02-24 12:19:38 +00:00
David Maciejak 62405fbb75 Detect and override illegal window size hints v2
The patch is trying to mitigate and properly address the issue described at
https://github.com/window-maker/wmaker/issues/26
A buggy application (in that example virtualbox) is requesting a window size creation
that is way too big and basically at the limit of X11 protocol
(width and height are defined as CARD16).
See details at https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html
During the tests, virtualbox has been seen requesting for window creation of size 843x65508.
Even xprop is reporting incorrect values.

There had been an attempt before with the commit
https://repo.or.cz/wmaker-crm.git?a=commit;h=6668715402a5d8e2ecda6702076a06bf8988721e

But the patch is broken and not implemented at the right place.
As described in the wWindowConfigure function header, the size passed by the client app
should not be trusted and should be vetted with a prior call to wWindowConstrainSize.
wWindowConstrainSize call was missing only once in the wClientConfigure function from client.c
What wWindowConstrainSize doing now is basically setting a failsafe window size fo 640x480
if both width and height are above the size of CARD16.
If only one dimension is oversized, it's setting a default 4/3 window ratio.
Oversized here has not been changed and it's defined in windowmaker as double the screen size.
2023-02-22 20:10:31 +00:00
David Maciejak f1fef40f0d Make window maximize state persistent
Window maximize state is not persistent between windowmaker sessions.
This patch is updating the save and restore workspace state functions
to update the state in the WMSTATE file.
2023-02-21 18:16:35 +00:00
David Maciejak 2fb9308a67 Info Panel: Add libXRes info if supported
If windowmaker was compiled with libXRes,
add XRes info in the "Additional support" section.

Take also the chance to remove the mode +x on the source code file.
2023-02-20 23:07:02 +00:00
David Maciejak d902477efd Set missing WM_COMMAND using pid given from libXRes
For apps which are not setting the window WM_COMMAND property like those old
apps using Motif toolkit (I am thinking of NEdit for example)
it's bringing some issues in windowmaker which is relying on it for a few interactions.
Especially,
*an app without WM_COMMAND will not be saved during the workspace state
(so session restore is not working for them)
*when added to the dock, the settings parameters are empty and need to be filled
*cannot autostart from the dock (even if the settings are manually filled and saved)
*right click on the app titlebar, and choosing Launch has no effect

Most of the time, those apps are also not setting the X11_NET_WM_PID property.
With the pid we could have a chance to find the running program.
To link a window to a pid, there is the X11 Resource extension library (libXRes).
After checking, gnome and xfce are also using the same method to handle such issues.

The patch is checking if the libXRes is present on the system (but it's not mandatory to compile).
Then, it adds a layer on top of wNETWMGetPidForWindow to not only check the window property
but if necessary to get the underlying pid from libXRes if available.
That's solving the points mentioned above.
2023-02-20 15:00:55 +00:00
David Maciejak 5ee19c2308 Allow WM_COMMAND-less app to autostart
For apps which are not setting the window WM_COMMAND property like those old
apps using Motif toolkit (I am thinking of NEdit for example)
it's bringing some issues in windowmaker which is relying on it for a few interactions.
Especially,
*an app without WM_COMMAND will not be saved during the workspace state
(so session restore is not working for them)
*when added to the dock, the settings parameters are empty and need to be filled
*cannot autostart from the dock (even if the settings are manually filled and saved)
*right click on the app titlebar, and choosing Launch has no effect

The patch below allows the workspace state to be saved for those apps without WM_COMMAND
that have been launched from the dock. We are just reusing what have been set in the
Application Path Settings of the dock app (and it does not require extra libs like libXRes).
2023-02-20 15:00:55 +00:00
David Maciejak fabd4252ab Allow exit panel to be bound to a key shortcut
While debugging the save/restore workspace state, I found quite
useful to be able to exit windowmaker using a key shortcut.
2023-02-20 15:00:55 +00:00
David Maciejak 630e9292c2 Factorize duplicate run command code
Run command from the menu and run command from the key shortcut are from two different codes.
Merge them into one function instead.
2023-02-19 10:10:49 +00:00
David Maciejak 14d1b8197a WRaster: Avoid undefined setjmp() behavior with libjpeg
Fix compiler warning:
load_jpeg.c: In function 'RLoadJPEG':
load_jpeg.c:100:17: warning: variable 'image' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]

As it was not working to only set the RImage *image as volatile,
I had to refactor the code by following the example from
https://github.com/libjpeg-turbo/libjpeg-turbo/commit/410c028f3396d1fa9bcc72608079ff4d3d76b03e#diff-e7cb632359a2be17c1008b50f9ec85691cd5d66834d5fe8f63ef65ceb06682ee
2023-02-19 10:10:41 +00:00
David Maciejak 4d658341d2 Add support for _NET_WM_FULLSCREEN_MONITORS
This patch adds the _NET_WM_FULLSCREEN_MONITORS hint as defined in EWMH which is based on Xinerama.
It's allowing a window to be displayed fullscreen on multiple monitors.

Issue mentioned at https://github.com/window-maker/wmaker/issues/8
Specs at https://specifications.freedesktop.org/wm-spec/1.5/ar01s06.html#idm45763309187776
GTK test program used https://bugzilla.gnome.org/show_bug.cgi?id=414476
2023-02-18 08:41:08 +00:00
David Maciejak ac75047aef Fix mini workspace compiler warnings
The patch is to fix warnings like:
wsmap.c: In function "update_mini_workspace":
wsmap.c:451:55: warning: "%d" directive output may be truncated writing between 1 and 11 bytes into a region of size 10 [-Wformat-truncation=]
  451 |                         snprintf(name, sizeof(name), "%d", general_index);
2023-02-17 21:51:06 +00:00
David Maciejak 6d6f9f6ff5 Info Panel: Fix uninitialized posn variable 2023-02-16 11:34:54 +00:00
David Maciejak 370adc94e7 Ignore WM_NORMAL_HINTS resize increment for maximized windows
If you are trying to maximize old apps that are setting a resize increment
in term of WM_NORMAL_HINTS notion the window will not be maximized fully (by a few pixels).
It's easy to reproduce with xterm, ctrl double click on the title bar.
xprop extract sample is giving:
program specified resize increment: 6 by 13

For those maximized windows the patch is just ignoring the resize increment.
Seems the same issue happened on that project
https://github.com/paperwm/PaperWM/issues/106
2023-02-16 01:21:25 +00:00
David Maciejak 532acdc443 WRaster: Avoid types deprecated with libtiff 4.3
This patch is fixing compiler warnings like:

load_tiff.c:42:9: warning: 'uint16' is deprecated [-Wdeprecated-declarations]
load_tiff.c:43:9: warning: 'uint32' is deprecated [-Wdeprecated-declarations]

As starting from libtiff 4.3, released in April 2021, types were moved
from uint16 to uint16_t and uint32 to uint32_t respectively.

See https://libtiff.gitlab.io/libtiff/releases/v4.3.0.html
2023-02-15 11:24:09 +00:00
David Maciejak d7d38aa443 Info Panel: display more OS details
Rely on old utsname and os-release (http://0pointer.de/blog/projects/os-release) when available
to display more underlying OS details in the Info panel.
The idea is when someone creates a bug entry we can request them to copy/paste that screen
to give more info about the context that could help us debug the issue.
For example, on my current system it's displaying:
"Running on: Ubuntu 22.10 (x86_64)"
2023-02-15 09:37:06 +00:00
David Maciejak a6209cc89b Set a better exit panel message
Replace the exit window manager generic message with Window Maker term instead.
2023-02-15 09:37:06 +00:00
David Maciejak 01bd523cee WINGs: allow keypad enter key to validate button
This patch allows the keypad enter key to validate the button click action.
2023-02-15 09:37:06 +00:00
David Maciejak 45ab72a78a InfoPanel: fix out of display text
When debug is enabled, the memory allocated details is supposed to display the free chunks
but as the text length is too long it's getting out of the display area.
This patch is increasing the window width to handle such case.
2023-02-13 13:10:14 +00:00
David Maciejak 437b76812d Info Panel: mallinfo is deprecated use mallinfo2 instead
Replacing mallinfo with mallinfo2.

The fields of the mallinfo structure that is returned by the
older mallinfo() function are typed as int.  However, because
some internal bookkeeping values may be of type long, the
reported values may wrap around zero and thus be inaccurate.
2023-02-11 10:35:23 +00:00
David Maciejak e3ee459a78 Info Panel: use system time to get the current year
Use the system date to get the current year to insert inside the copyright line.
So no need to update that string anymore.
2023-02-11 10:33:22 +00:00
David Maciejak d70b546f2e Fix wrong XKeycodeToKeysym index value
XKeycodeToKeysym was deprecated some time ago and wmaker code was patched to use the definition from XKBlib instead.
(https://repo.or.cz/wmaker-crm.git?a=commit;h=0382dd5dd7ecae2112a0c6366eaf9e6ab68ad354)

Before being deprecated,  XKeycodeToKeysym was prototyped at X11/Xlib.h as
KeySym XKeycodeToKeysym(display, keycode, index)

Now it's available in X11/XKBlib.h as
KeySym XkbKeycodeToKeysym(display, keycode, group, level)

Basically level now which is the 4th parameter is our old index variable (3rd parameter).

On systems which don't have xkb supported the value set for index is wrong.
As seen in old patch at https://repo.or.cz/wmaker-crm.git/blobdiff/139f912e618870cc7fd908099f203450547eb658..43c3526d2120712f72579398b73ef92283d9078b:/WPrefs.app/MouseSettings.c
we should pass the l value to old XKeycodeToKeysym function and not the 0 value which is used for the group in the new XkbKeycodeToKeysym definition.
2023-02-11 10:30:52 +00:00
David Maciejak 812930b7cd Fix icon.c unused variable compiler warning
Just to please the compiler as it's reporting:
icon.c: In function 'get_icon_cache_path':
icon.c:425:13: warning: unused variable 'len' [-Wunused-variable]
2023-02-11 10:30:02 +00:00
David Maciejak 2a14004fc3 SwitchPanel: make sure WMRetainColor and WMReleaseColor calls are even
The number of calls to WMRetainColor for a color in use should the same as the number of calls to WMReleaseColor
to free that color. In case of discrepancy, random crashes can happen and memory is not freed properly.
To debug that issue I checked the retained colors when the switchpanel is opened and then checked if those colors are properly released once the panel is closed.

This patch fixes the issue mentioned at https://github.com/window-maker/wmaker/issues/22
2023-02-10 11:24:55 +00:00
David Maciejak 04e9f33437 WINGs: Fix incorrect findCloseColor exact flag value
In case the color cannot be allocated exactly by createRGBAColor function,
the findCloseColor function is used as a failover function to find a color close to the requested color.
By definition that color is then not exact.
createRGBAColor exact flag should be 1 while findCloseColor exact flag should be 0
2023-02-10 11:24:44 +00:00
David Maciejak 150816c687 Fix missing linefeed on the error message
Just to display the error message properly in case there is no display.
2023-02-08 00:14:48 +00:00
48 changed files with 727 additions and 255 deletions
+6
View File
@@ -1,3 +1,9 @@
Changes since wmaker 0.95.10:
............................
- added W_KeycodeToKeysym to replace XKeycodeToKeysym/XkbKeycodeToKeysym calls
Changes since wmaker 0.92.0:
............................
+3 -1
View File
@@ -1,7 +1,9 @@
** API and ABI modifications since wmaker 0.92.0
** API and ABI modifications since wmaker 0.95.10
----------------------------------------------------
** libWINGs **
<WINGsP.h>
W_KeycodeToKeysym ADDED
struct W_DragDestinationInfo: new members added SIZE CHANGE
<WINGs.h>
+1 -1
View File
@@ -26,7 +26,7 @@
#include <WINGs/WUtil.h>
#include <X11/Xlib.h>
#define WINGS_H_VERSION 20210726
#define WINGS_H_VERSION 20230226
#ifdef __cplusplus
+2
View File
@@ -494,6 +494,8 @@ void W_SetPreeditPositon(W_View *view, int x, int y);
int W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer,
int buflen, KeySym *keysym, Status *status);
KeySym W_KeycodeToKeysym(Display *display, KeyCode keycode, int index);
/* ---[ wmisc.c ]--------------------------------------------------------- */
+1 -1
View File
@@ -612,7 +612,7 @@ static void menu_parser_condition_ifmacro(WMenuParser parser, Bool check_exists)
macro = menu_parser_find_macro(parser, macro_name);
parser->cond.stack[0].skip =
((check_exists) && (macro == NULL)) ||
((!check_exists) && (macro != NULL)) ;
((!check_exists) && (macro != NULL));
}
strcpy(parser->cond.stack[0].name, cmd_name);
+2 -1
View File
@@ -279,7 +279,8 @@ WParserMacro *menu_parser_find_macro(WMenuParser parser, const char *name)
continue;
return macro;
check_next_macro: ;
check_next_macro:
;
}
return NULL;
}
+3 -3
View File
@@ -51,7 +51,7 @@ static WMColor *findCloseColor(WMScreen * scr, unsigned short red, unsigned shor
color->refCount = 1;
color->color = xcolor;
color->alpha = alpha;
color->flags.exact = 1;
color->flags.exact = 0;
color->gc = NULL;
return color;
@@ -91,7 +91,7 @@ WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short gre
color = findCloseColor(scr, red, green, blue, 0xffff);
}
if (!color)
color = WMBlackColor(scr);
color = scr->black;
return color;
}
@@ -117,7 +117,7 @@ WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short gr
color = findCloseColor(scr, red, green, blue, alpha);
}
if (!color)
color = WMBlackColor(scr);
color = scr->black;
return color;
}
+3
View File
@@ -253,6 +253,9 @@ WMFrame *WMCreateFrame(WMWidget * parent)
static void destroyFrame(Frame * fPtr)
{
if (fPtr->textColor)
WMReleaseColor(fPtr->textColor);
if (fPtr->caption)
wfree(fPtr->caption);
+32
View File
@@ -213,3 +213,35 @@ int W_LookupString(W_View *view, XKeyPressedEvent *event, char *buffer, int bufl
#endif
return XLookupString(event, buffer, buflen, keysym, (XComposeStatus *) status);
}
/*
* Map a keycode to the corresponding keysym
* To replace the deprecated X11 function XKeycodeToKeysym
*/
KeySym W_KeycodeToKeysym(Display *display, KeyCode keycode, int index)
{
static int min_kc = -1;
static int max_kc;
int num_syms;
KeySym *key_syms;
KeySym ks;
if (min_kc == -1) {
(void) XDisplayKeycodes(display, &min_kc, &max_kc);
}
if (keycode < min_kc || keycode > max_kc || index < 0) {
return NoSymbol;
}
key_syms = XGetKeyboardMapping(display, keycode, 1, &num_syms);
if (index >= num_syms) {
XFree(key_syms);
return NoSymbol;
}
ks = key_syms[index];
XFree(key_syms);
return ks;
}
+3 -3
View File
@@ -25,7 +25,7 @@ static void handleKeyPress(XEvent * event, void *clientData)
XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
if (ksym == XK_Return && panel->defBtn) {
if ((ksym == XK_Return || ksym == XK_KP_Enter) && panel->defBtn) {
WMPerformButtonClick(panel->defBtn);
} else if (ksym == XK_Escape) {
if (panel->altBtn || panel->othBtn) {
@@ -421,7 +421,7 @@ static void handleKeyPress2(XEvent * event, void *clientData)
XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
if (ksym == XK_Return && panel->defBtn) {
if ((ksym == XK_Return || ksym == XK_KP_Enter) && panel->defBtn) {
WMPerformButtonClick(panel->defBtn);
} else if (ksym == XK_Escape) {
if (panel->altBtn) {
@@ -709,7 +709,7 @@ static void handleKeyPress3(XEvent * event, void *clientData)
XLookupString(&event->xkey, NULL, 0, &ksym, NULL);
if (ksym == XK_Return && panel->defBtn) {
if ((ksym == XK_Return || ksym == XK_KP_Enter) && panel->defBtn) {
WMPerformButtonClick(panel->defBtn);
} else if (ksym == XK_Escape) {
if (panel->altBtn) {
+1 -1
View File
@@ -622,7 +622,7 @@ static void paintText(Text * tPtr)
TextBlock *tb;
WMFont *font;
const char *text;
int len, y, c, s, done = False, dir /* 1 = down */ ;
int len, y, c, s, done = False, dir; /* dir 1 = down */
WMScreen *scr = tPtr->view->screen;
Display *dpy = tPtr->view->screen->display;
Window win = tPtr->view->window;
+1 -1
View File
@@ -661,7 +661,7 @@ static void didResizeTextField(W_ViewDelegate * self, WMView * view)
tPtr->offsetWidth = WMAX((tPtr->view->size.height - WMFontHeight(tPtr->font)) / 2, 1);
tPtr->usableWidth = tPtr->view->size.width - 2 * tPtr->offsetWidth /*+ 2 */ ;
tPtr->usableWidth = tPtr->view->size.width - 2 * tPtr->offsetWidth;
}
static char *makeHiddenString(int length)
+54 -12
View File
@@ -156,6 +156,7 @@ static const struct {
{ "WindowRelaunchKey", N_("Launch new instance of application") },
{ "ScreenSwitchKey", N_("Switch to Next Screen/Monitor") },
{ "RunKey", N_("Run application") },
{ "ExitKey", N_("Exit Window Maker") },
{ "DockRaiseLowerKey", N_("Raise/Lower Dock") },
{ "ClipRaiseLowerKey", N_("Raise/Lower Clip") }
#ifdef XKB_MODELOCK
@@ -316,11 +317,8 @@ char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case)
if (ev.type == KeyPress && ev.xkey.keycode != 0) {
numlock_mask = NumLockMask(dpy);
if (xext_xkb_supported)
/* conditional mask check to get numeric keypad keys */
ksym = XkbKeycodeToKeysym(dpy, ev.xkey.keycode, 0, ev.xkey.state & numlock_mask?1:0);
else
ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
/* conditional mask check to get numeric keypad keys */
ksym = W_KeycodeToKeysym(dpy, ev.xkey.keycode, ev.xkey.state & numlock_mask?1:0);
if (!IsModifierKey(ksym)) {
if (convert_case) {
@@ -368,6 +366,36 @@ char *capture_shortcut(Display *dpy, Bool *capturing, Bool convert_case)
return wstrdup(buffer);
}
/*
* check if the keystr entered is already set to another action
* if found it returns the position in the keyOptions
*/
static int isKeySet(_Panel *panel, char *keystr)
{
int i;
char *str;
for (i = 0; i < panel->actionCount; i++) {
str = NULL;
if (panel->shortcuts[i]) {
str = wtrimspace(panel->shortcuts[i]);
if (strlen(str) == 0) {
wfree(str);
str = NULL;
}
}
if (str) {
if (strcmp(keystr, str) == 0) {
wfree(str);
return i;
}
wfree(str);
}
}
return -1;
}
static void captureClick(WMWidget * w, void *data)
{
_Panel *panel = (_Panel *) data;
@@ -382,17 +410,31 @@ static void captureClick(WMWidget * w, void *data)
XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, GrabModeAsync, GrabModeAsync, CurrentTime);
shortcut = capture_shortcut(dpy, &panel->capturing, 1);
if (shortcut) {
int key_idx = -1;
int row = WMGetListSelectedItemRow(panel->actLs);
WMSetTextFieldText(panel->shoT, shortcut);
if (row >= 0) {
if (panel->shortcuts[row])
wfree(panel->shortcuts[row]);
panel->shortcuts[row] = shortcut;
key_idx = isKeySet(panel, shortcut);
if (key_idx >= 0 && (key_idx != row)) {
char *msg;
WMRedisplayWidget(panel->actLs);
} else {
msg = wstrconcat(_("Key shortcut already in use by the "), _(keyOptions[key_idx].title));
WMRunAlertPanel(WMWidgetScreen(w), GetWindow(),
_("Error"),
msg,
_("OK"), NULL, NULL);
wfree(msg);
wfree(shortcut);
} else {
WMSetTextFieldText(panel->shoT, shortcut);
if (row >= 0) {
if (panel->shortcuts[row])
wfree(panel->shortcuts[row]);
panel->shortcuts[row] = shortcut;
WMRedisplayWidget(panel->actLs);
} else {
wfree(shortcut);
}
}
}
}
+1 -4
View File
@@ -381,10 +381,7 @@ static void fillModifierPopUp(WMPopUpButton * pop)
if (mapping->modifiermap[idx] != 0) {
int l;
for (l = 0; l < 4; l++) {
if (xext_xkb_supported)
ksym = XkbKeycodeToKeysym(dpy, mapping->modifiermap[idx], 0, l);
else
ksym = XKeycodeToKeysym(dpy, mapping->modifiermap[idx], 0);
ksym = W_KeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
if (ksym != NoSymbol)
break;
}
+1 -1
View File
@@ -33,6 +33,7 @@
#include <wraster.h>
#include <WINGs/WINGs.h>
#include <WINGs/WINGsP.h>
/* Needed for HAVE_LIBINTL_H and EXTENDED_WINDOWSHORTCUT */
#include "../src/wconfig.h"
@@ -54,7 +55,6 @@
/****/
extern char *NOptionValueChanged;
extern Bool xext_xkb_supported;
typedef struct _Panel Panel;
-4
View File
@@ -35,8 +35,6 @@
#endif
char *NOptionValueChanged = "NOptionValueChanged";
Bool xext_xkb_supported = False;
#define MAX_DEATHS 64
@@ -157,8 +155,6 @@ int main(int argc, char **argv)
exit(0);
}
xext_xkb_supported = XkbQueryExtension(dpy, NULL, NULL, NULL, NULL, NULL);
WMPLSetCaseSensitive(False);
Initialize(scr);
+1 -4
View File
@@ -171,10 +171,7 @@ static void x_reset_modifier_mapping(Display * display)
KeySym sym;
if (code) {
if (xext_xkb_supported)
sym = XkbKeycodeToKeysym(display, code, 0, column);
else
sym = XKeycodeToKeysym(display, code, column);
sym = W_KeycodeToKeysym(display, code, column);
} else {
sym = NoSymbol;
}
+1
View File
@@ -232,6 +232,7 @@
WindowRelaunchKey = None;
ScreenSwitchKey = None;
RunKey = None;
ExitKey = None;
NormalCursor = (builtin, left_ptr);
ArrowCursor = (builtin, top_left_arrow);
MoveCursor = (builtin, fleur);
+17 -5
View File
@@ -78,9 +78,9 @@ WRASTER_VERSION=$WRASTER_CURRENT:$WRASTER_REVISION:$WRASTER_AGE
AC_SUBST(WRASTER_VERSION)
dnl
dnl libWINGs
WINGS_CURRENT=4
WINGS_CURRENT=5
WINGS_REVISION=0
WINGS_AGE=1
WINGS_AGE=2
WINGS_VERSION=$WINGS_CURRENT:$WINGS_REVISION:$WINGS_AGE
AC_SUBST(WINGS_VERSION)
dnl
@@ -270,8 +270,8 @@ supported_gfx=""
dnl Platform-specific Makefile setup
dnl ================================
AS_CASE(["$host"],
[*-*-linux*|*-*-cygwin*|*-gnu*], [WM_OSDEP="linux" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600"],
[*-*-freebsd*|*-k*bsd-gnu*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -DFREEBSD"],
[*-*-linux*|*-*-cygwin*|*-gnu*], [WM_OSDEP="linux" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=700"],
[*-*-freebsd*|*-k*bsd-gnu*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=700 -DFREEBSD"],
[*-*-netbsd*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -DNETBSD"],
[*-*-openbsd*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -DOPENBSD"],
[*-*-dragonfly*], [WM_OSDEP="bsd" ; CPPFLAGS="$CPPFLAGS -DDRAGONFLYBSD"],
@@ -387,7 +387,7 @@ AC_FUNC_MEMCMP
AC_FUNC_VPRINTF
WM_FUNC_SECURE_GETENV
AC_CHECK_FUNCS(gethostname select poll strcasecmp strncasecmp \
setsid mallinfo mkstemp sysconf)
setsid mallinfo2 mkstemp sysconf)
AC_SEARCH_LIBS([strerror], [cposix])
dnl nanosleep is generally available in standard libc, although not always the
@@ -580,6 +580,18 @@ AS_IF([test "x$enable_wmreplace" = "xyes"],
[define to support ICCCM protocol for window manager replacement])
supported_xext="$supported_xext WMReplace"])
dnl XRes support
dnl ==============
m4_divert_push([INIT_PREPARE])dnl
AC_ARG_ENABLE([res],
[AS_HELP_STRING([--disable-res], [disable resource window extension support])],
[AS_CASE(["$enableval"],
[yes|no], [],
[AC_MSG_ERROR([bad value $enableval for --enable-res]) ]) ],
[enable_res=auto])
m4_divert_pop([INIT_PREPARE])dnl
WM_XEXT_CHECK_XRES
dnl XShape support
dnl ==============
+4
View File
@@ -551,6 +551,10 @@ Disable use of the @emph{MIT shared memory} extension.
This will slow down texture generation a little bit, but in some cases it seems to be necessary due
to a bug that manifests as messed icons and textures.
@item --disable-res
Disables support for @emph{XRes} resource window extension support.
Which is used to find the underlying processes (and PIDs) displaying the windows.
@item --disable-shape
Disables support for @emph{shaped} windows (for @command{oclock}, @command{xeyes}, etc.).
+27
View File
@@ -16,6 +16,33 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# WM_XEXT_CHECK_XRES
# --------------------
#
# Check for the X Resource Window extension
# The check depends on variable 'enable_xshape' being either:
# yes - detect, fail if not found
# no - do not detect, disable support
# auto - detect, disable if not found
#
# When found, append appropriate stuff in XLIBS, and append info to
# the variable 'supported_xext'
# When not found, append info to variable 'unsupported'
AC_DEFUN_ONCE([WM_XEXT_CHECK_XRES],
[WM_LIB_CHECK([XRes], [-lXRes], [XResQueryClientIds], [$XLIBS],
[wm_save_CFLAGS="$CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl
@%:@include <X11/extensions/XRes.h>
], [dnl
XResQueryClientIds(NULL, 0, NULL, NULL, NULL);])]
[],
[AC_MSG_ERROR([found $CACHEVAR but cannot compile using XRes header])])
CFLAGS="$wm_save_CFLAGS"],
[supported_xext], [XLIBS], [enable_res], [-])dnl
]) dnl AC_DEFUN
# WM_XEXT_CHECK_XSHAPE
# --------------------
#
+48
View File
@@ -912,6 +912,54 @@ void wUnmaximizeWindow(WWindow *wwin)
WMPostNotificationName(WMNChangedState, wwin, "maximize");
}
#ifdef USE_XINERAMA
void wFullscreenMonitorsWindow(WWindow *wwin, unsigned long top, unsigned long bottom,
unsigned long left, unsigned long right)
{
int i;
long monitor;
WMRect rect1, rect2;
if ((int)top < wwin->screen_ptr->xine_info.count &&
(int)bottom < wwin->screen_ptr->xine_info.count &&
(int)left < wwin->screen_ptr->xine_info.count &&
(int)right < wwin->screen_ptr->xine_info.count) {
wwin->flags.fullscreen_monitors[0] = top;
wwin->flags.fullscreen_monitors[1] = bottom;
wwin->flags.fullscreen_monitors[2] = left;
wwin->flags.fullscreen_monitors[3] = right;
} else {
wwin->flags.fullscreen_monitors[0] = -1;
return;
}
wwin->flags.fullscreen = True;
wWindowConfigureBorders(wwin);
ChangeStackingLevel(wwin->frame->core, WMFullscreenLevel);
wwin->bfs_geometry.x = wwin->frame_x;
wwin->bfs_geometry.y = wwin->frame_y;
wwin->bfs_geometry.width = wwin->frame->core->width;
wwin->bfs_geometry.height = wwin->frame->core->height;
i = 0;
monitor = wwin->flags.fullscreen_monitors[i];
rect1 = wwin->screen_ptr->xine_info.screens[monitor];
for (i = 1; i <= 3; i++) {
monitor = wwin->flags.fullscreen_monitors[i];
rect2 = wwin->screen_ptr->xine_info.screens[monitor];
wGetRectUnion(&rect1, &rect2, &rect1);
}
wWindowConfigure(wwin, rect1.pos.x, rect1.pos.y, rect1.size.width, rect1.size.height);
wwin->screen_ptr->bfs_focused_window = wwin->screen_ptr->focused_window;
wSetFocusTo(wwin->screen_ptr, wwin);
WMPostNotificationName(WMNChangedState, wwin, "fullscreen");
}
#endif
void wFullscreenWindow(WWindow *wwin)
{
int head;
+3
View File
@@ -75,6 +75,9 @@ void wArrangeIcons(WScreen *scr, Bool arrangeAll);
void wMakeWindowVisible(WWindow *wwin);
void wFullscreenMonitorsWindow(WWindow *wwin, unsigned long top, unsigned long bottom,
unsigned long left, unsigned long right);
void wFullscreenWindow(WWindow *wwin);
void wUnfullscreenWindow(WWindow *wwin);
+1
View File
@@ -244,6 +244,7 @@ void wClientConfigure(WWindow * wwin, XConfigureRequestEvent * xcre)
if (nheight != wwin->old_geometry.height)
wwin->flags.maximized &= ~(MAX_VERTICAL | MAX_LEFTHALF | MAX_RIGHTHALF | MAX_MAXIMUS);
wWindowConstrainSize(wwin, (unsigned int *)&nwidth, (unsigned int *)&nheight);
wWindowConfigure(wwin, nx, ny, nwidth, nheight);
wwin->old_geometry.x = nx;
wwin->old_geometry.y = ny;
+3 -1
View File
@@ -154,7 +154,7 @@ static WDECallbackUpdate setModifierKeyLabels;
static WDECallbackConvert getCursor;
static WDECallbackUpdate setCursor;
static WDECallbackUpdate updateDock ;
static WDECallbackUpdate updateDock;
/*
* Tables to convert strings to enumeration values.
@@ -788,6 +788,8 @@ WDefaultEntry optionList[] = {
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"RunKey", "None", (void *)WKBD_RUN,
NULL, getKeybind, setKeyGrab, NULL, NULL},
{"ExitKey", "None", (void *)WKBD_EXIT,
NULL, getKeybind, setKeyGrab, NULL, NULL},
#ifdef KEEP_XKB_LOCK_STATUS
{"ToggleKbdModeKey", "None", (void *)WKBD_TOGGLE,
+99 -12
View File
@@ -36,6 +36,8 @@
#include <dirent.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <sys/utsname.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
@@ -1153,7 +1155,7 @@ typedef struct {
#define COPYRIGHT_TEXT \
"Copyright \xc2\xa9 1997-2006 Alfredo K. Kojima\n"\
"Copyright \xc2\xa9 1998-2006 Dan Pascu\n"\
"Copyright \xc2\xa9 2013-2020 Window Maker Developers Team"
"Copyright \xc2\xa9 2013-%hu Window Maker Developers Team"
static InfoPanel *infoPanel = NULL;
@@ -1171,6 +1173,57 @@ static void destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
infoPanel = NULL;
}
char *getPrettyOSName(void)
{
char line[200];
char *token;
char *posn = NULL;
const char s[2] = "=";
FILE *fp;
fp = fopen("/etc/os-release", "r");
if (!fp) {
fp = fopen("/usr/lib/os-release", "r");
if (!fp) {
wwarning(_("no os-release file on the system"));
return NULL;
}
}
while (fgets(line, sizeof(line), fp) != NULL) {
if (strncmp(line, "PRETTY_NAME", strlen("PRETTY_NAME")) == 0) {
line[strcspn(line, "\r\n")] = 0;
token = strtok(line, s);
if (token) {
//get straight to the second part of the line
token = strtok(NULL, s);
if (token) {
//removing potential quotes
char *dst = token;
char *src = token;
char c;
while ((c = *src++) != '\0') {
if (c == '\\') {
*dst++ = c;
if ((c = *src++) == '\0')
break;
*dst++ = c;
} else if (c != '"' && c != '\'')
*dst++ = c;
}
*dst = '\0';
posn = wmalloc(strlen(token) + 1);
strcpy(posn, token);
}
}
break;
}
}
fclose(fp);
return posn;
}
void wShowInfoPanel(WScreen *scr)
{
InfoPanel *panel;
@@ -1194,6 +1247,17 @@ void wShowInfoPanel(WScreen *scr)
};
int wmScaleWidth, wmScaleHeight;
int pwidth, pheight;
int current_year = 2020;
time_t s;
struct tm *current_time;
struct utsname uts;
s = time(NULL);
if (s) {
current_time = localtime(&s);
if (current_time->tm_year > (current_year - 1900))
current_year = current_time->tm_year + 1900;
}
if (infoPanel) {
if (infoPanel->scr == scr) {
@@ -1209,8 +1273,12 @@ void wShowInfoPanel(WScreen *scr)
panel->win = WMCreateWindow(scr->wmscreen, "info");
WMGetScaleBaseFromSystemFont(scr->wmscreen, &wmScaleWidth, &wmScaleHeight);
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO2) && defined(DEBUG)
pwidth = WMScaleX(412);
#else
pwidth = WMScaleX(382);
pheight = WMScaleY(250);
#endif
pheight = WMScaleY(270);
WMResizeWidget(panel->win, pwidth, pheight);
logo = WMCreateApplicationIconBlendedPixmap(scr->wmscreen, (RColor *) NULL);
@@ -1274,9 +1342,11 @@ void wShowInfoPanel(WScreen *scr)
panel->copyrL = WMCreateLabel(panel->win);
WMResizeWidget(panel->copyrL, WMScaleX(360), WMScaleY(60));
WMMoveWidget(panel->copyrL, WMScaleX(15), WMScaleY(190));
WMMoveWidget(panel->copyrL, WMScaleX(15), WMScaleY(210));
WMSetLabelTextAlignment(panel->copyrL, WALeft);
WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
snprintf(buffer, sizeof(buffer), COPYRIGHT_TEXT, current_year);
WMSetLabelText(panel->copyrL, buffer);
font = WMSystemFontOfSize(scr->wmscreen, WMScaleY(11));
if (font) {
WMSetLabelFont(panel->copyrL, font);
@@ -1285,9 +1355,19 @@ void wShowInfoPanel(WScreen *scr)
}
strbuf = NULL;
if (uname(&uts) != -1) {
char *posn = getPrettyOSName();
if (posn) {
snprintf(buffer, sizeof(buffer), _("Running on: %s (%s)\n"), posn, uts.machine);
free(posn);
}
else
snprintf(buffer, sizeof(buffer), _("Running on: %s (%s)\n"), uts.sysname, uts.machine);
strbuf = wstrappend(strbuf, buffer);
}
snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
(unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
strbuf = wstrappend(strbuf, buffer);
switch (scr->w_depth) {
@@ -1307,14 +1387,14 @@ void wShowInfoPanel(WScreen *scr)
break;
}
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO2)
{
struct mallinfo ma = mallinfo();
struct mallinfo2 ma = mallinfo2();
snprintf(buffer, sizeof(buffer),
#ifdef DEBUG
_("Total memory allocated: %i kB (in use: %i kB, %d free chunks).\n"),
_("Total memory allocated: %lu kB (in use: %lu kB, %lu free chunks)\n"),
#else
_("Total memory allocated: %i kB (in use: %i kB).\n"),
_("Total memory allocated: %lu kB (in use: %lu kB)\n"),
#endif
(ma.arena + ma.hblkhd) / 1024,
(ma.uordblks + ma.hblkhd) / 1024
@@ -1353,6 +1433,10 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, ", XDnD");
#endif
#ifdef USE_XRES
strbuf = wstrappend(strbuf, ", XRes");
#endif
#ifdef USE_MAGICK
strbuf = wstrappend(strbuf, ", ImageMagick");
#endif
@@ -1365,7 +1449,7 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, _("Xinerama: "));
{
char tmp[128];
snprintf(tmp, sizeof(tmp) - 1, _("%d head(s) found."), scr->xine_info.count);
snprintf(tmp, sizeof(tmp) - 1, _("%d head(s) found"), scr->xine_info.count);
strbuf = wstrappend(strbuf, tmp);
}
#endif
@@ -1377,11 +1461,14 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, _("supported"));
else
strbuf = wstrappend(strbuf, _("unsupported"));
strbuf = wstrappend(strbuf, ".");
#endif
panel->infoL = WMCreateLabel(panel->win);
WMResizeWidget(panel->infoL, WMScaleX(350), WMScaleY(80));
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO2) && defined(DEBUG)
WMResizeWidget(panel->infoL, WMScaleX(380), WMScaleY(100));
#else
WMResizeWidget(panel->infoL, WMScaleX(350), WMScaleY(100));
#endif
WMMoveWidget(panel->infoL, WMScaleX(15), WMScaleY(115));
WMSetLabelText(panel->infoL, strbuf);
font = WMSystemFontOfSize(scr->wmscreen, WMScaleY(11));
+7 -14
View File
@@ -1852,21 +1852,14 @@ static void handleKeyPress(XEvent * event)
case WKBD_RUN:
{
char *cmdline;
ExecuteInputCommand(scr, _("exec %A(Run, Type command:)"));
break;
}
cmdline = ExpandOptions(scr, _("exec %A(Run,Type command to run:)"));
if (cmdline) {
XGrabPointer(dpy, scr->root_win, True, 0,
GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime);
XSync(dpy, False);
ExecuteShellCommand(scr, cmdline);
wfree(cmdline);
XUngrabPointer(dpy, CurrentTime);
XSync(dpy, False);
}
case WKBD_EXIT:
{
/* quick mode is not allowed to prevent inadvertently call */
ExecuteExitCommand(scr, 0);
break;
}
+1 -1
View File
@@ -422,7 +422,7 @@ static char *get_icon_cache_path(void)
{
const char *prefix;
char *path;
int len, ret;
int ret;
prefix = wuserdatapath();
path = wstrconcat(prefix, CACHE_ICON_PATH "/");
+3
View File
@@ -145,6 +145,9 @@ enum {
/* open "run" dialog */
WKBD_RUN,
/* open "exit" dialog */
WKBD_EXIT,
#ifdef KEEP_XKB_LOCK_STATUS
WKBD_TOGGLE,
#endif
+15 -5
View File
@@ -56,6 +56,7 @@
#include "dialog.h"
#include "main.h"
#include "monitor.h"
#include "misc.h"
#include <WINGs/WUtil.h>
@@ -354,11 +355,19 @@ Bool RelaunchWindow(WWindow *wwin)
char **argv;
int argc;
char *command = NULL;
if (! XGetCommand(dpy, wwin->client_win, &argv, &argc) || argc == 0 || argv == NULL) {
command = GetCommandForWindow(wwin->client_win);
if (!command) {
#ifdef USE_XRES
werror("cannot relaunch the application because no associated process found");
#else
werror("cannot relaunch the application because no WM_COMMAND property is set");
#endif
return False;
}
} else
wtokensplit(command, &argv, &argc);
pid_t pid = fork();
@@ -384,18 +393,19 @@ Bool RelaunchWindow(WWindow *wwin)
} else if (pid < 0) {
werror("cannot fork a new process");
XFreeStringList(argv);
wfree(argv);
wfree(command);
return False;
} else {
_tuple *data = wmalloc(sizeof(_tuple));
data->scr = wwin->screen_ptr;
data->command = wtokenjoin(argv, argc);
data->command = command;
/* not actually a shell command */
wAddDeathHandler(pid, shellCommandHandler, data);
XFreeStringList(argv);
wfree(argv);
}
return True;
+1 -1
View File
@@ -2440,7 +2440,7 @@ static int restoreMenu(WScreen *scr, WMPropList *menu)
static int restoreMenuRecurs(WScreen *scr, WMPropList *menus, WMenu *menu, const char *path)
{
WMPropList *key, *entry;
char buffer[512];
char buffer[1024];
int i, x, y, res;
Bool lowered;
+61 -1
View File
@@ -38,6 +38,7 @@
#include <X11/XKBlib.h>
#include <WINGs/WUtil.h>
#include <WINGs/WINGsP.h>
#include <wraster.h>
#include "window.h"
@@ -53,6 +54,7 @@
#include "xmodifier.h"
#include "main.h"
#include "event.h"
#include "shutdown.h"
#define ICON_SIZE wPreferences.icon_size
@@ -679,6 +681,64 @@ char *ExpandOptions(WScreen *scr, const char *cmdline)
return NULL;
}
void ExecuteExitCommand(WScreen *scr, long quickmode)
{
static int inside = 0;
int result;
/* prevent reentrant calls */
if (inside)
return;
inside = 1;
#define R_CANCEL 0
#define R_EXIT 1
result = R_CANCEL;
if (quickmode == M_QUICK) {
result = R_EXIT;
} else {
int r, oldSaveSessionFlag;
oldSaveSessionFlag = wPreferences.save_session_on_exit;
r = wExitDialog(scr, _("Exit"),
_("Are you sure you want to quit Window Maker?"), _("Exit"), _("Cancel"), NULL);
if (r == WAPRDefault) {
result = R_EXIT;
} else if (r == WAPRAlternate) {
/* Don't modify the "save session on exit" flag if the
* user canceled the operation. */
wPreferences.save_session_on_exit = oldSaveSessionFlag;
}
}
if (result == R_EXIT)
Shutdown(WSExitMode);
#undef R_EXIT
#undef R_CANCEL
inside = 0;
}
void ExecuteInputCommand(WScreen *scr, const char *cmdline)
{
char *cmd;
cmd = ExpandOptions(scr, cmdline);
if (cmd) {
XGrabPointer(dpy, scr->root_win, True, 0,
GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime);
XSync(dpy, False);
ExecuteShellCommand(scr, cmd);
wfree(cmd);
XUngrabPointer(dpy, CurrentTime);
XSync(dpy, False);
}
}
void ParseWindowName(WMPropList *value, char **winstance, char **wclass, const char *where)
{
char *name;
@@ -781,7 +841,7 @@ char *GetShortcutKey(WShortKey key)
}
}
key_name = XKeysymToString(XkbKeycodeToKeysym(dpy, key.keycode, 0, 0));
key_name = XKeysymToString(W_KeycodeToKeysym(dpy, key.keycode, 0));
if (!key_name)
return NULL;
+4
View File
@@ -25,6 +25,8 @@
#include "keybind.h"
#include "appicon.h"
#define M_QUICK 1
Bool wFetchName(Display *dpy, Window win, char **winname);
Bool wGetIconName(Display *dpy, Window win, char **iconname);
Bool UpdateDomainFile(WDDomain * domain);
@@ -45,6 +47,8 @@ void SendHelperMessage(WScreen *scr, char type, int workspace, const char *msg);
char *ShrinkString(WMFont *font, const char *string, int width);
char *FindImage(const char *paths, const char *file);
char *ExpandOptions(WScreen * scr, const char *cmdline);
void ExecuteInputCommand(WScreen *scr, const char *cmdline);
void ExecuteExitCommand(WScreen *scr, long quickmode);
char *GetShortcutString(const char *text);
char *GetShortcutKey(WShortKey key);
char *EscapeWM_CLASS(const char *name, const char *class);
+2 -51
View File
@@ -142,66 +142,17 @@ static Shortcut *shortcutList = NULL;
*
*/
#define M_QUICK 1
/* menu commands */
static void execCommand(WMenu * menu, WMenuEntry * entry)
{
char *cmdline;
cmdline = ExpandOptions(menu->frame->screen_ptr, (char *)entry->clientdata);
XGrabPointer(dpy, menu->frame->screen_ptr->root_win, True, 0,
GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime);
XSync(dpy, 0);
if (cmdline) {
ExecuteShellCommand(menu->frame->screen_ptr, cmdline);
wfree(cmdline);
}
XUngrabPointer(dpy, CurrentTime);
XSync(dpy, 0);
ExecuteInputCommand(menu->frame->screen_ptr, (char *)entry->clientdata);
}
static void exitCommand(WMenu * menu, WMenuEntry * entry)
{
static int inside = 0;
int result;
ExecuteExitCommand(menu->frame->screen_ptr, (long)entry->clientdata);
/* prevent reentrant calls */
if (inside)
return;
inside = 1;
#define R_CANCEL 0
#define R_EXIT 1
result = R_CANCEL;
if ((long)entry->clientdata == M_QUICK) {
result = R_EXIT;
} else {
int r, oldSaveSessionFlag;
oldSaveSessionFlag = wPreferences.save_session_on_exit;
r = wExitDialog(menu->frame->screen_ptr, _("Exit"),
_("Exit window manager?"), _("Exit"), _("Cancel"), NULL);
if (r == WAPRDefault) {
result = R_EXIT;
} else if (r == WAPRAlternate) {
/* Don't modify the "save session on exit" flag if the
* user canceled the operation. */
wPreferences.save_session_on_exit = oldSaveSessionFlag;
}
}
if (result == R_EXIT)
Shutdown(WSExitMode);
#undef R_EXIT
#undef R_CANCEL
inside = 0;
}
static void shutdownCommand(WMenu * menu, WMenuEntry * entry)
+35 -3
View File
@@ -93,6 +93,7 @@ static WMPropList *sHost;
static WMPropList *sWorkspace;
static WMPropList *sShaded;
static WMPropList *sMiniaturized;
static WMPropList *sMaximized;
static WMPropList *sHidden;
static WMPropList *sGeometry;
static WMPropList *sShortcutMask;
@@ -112,6 +113,7 @@ static void make_keys(void)
sWorkspace = WMCreatePLString("Workspace");
sShaded = WMCreatePLString("Shaded");
sMiniaturized = WMCreatePLString("Miniaturized");
sMaximized = WMCreatePLString("Maximized");
sHidden = WMCreatePLString("Hidden");
sGeometry = WMCreatePLString("Geometry");
sDock = WMCreatePLString("Dock");
@@ -166,6 +168,22 @@ static unsigned getInt(WMPropList * value)
return n;
}
static unsigned getHex(WMPropList * value)
{
char *val;
unsigned n;
if (!WMIsPLString(value))
return 0;
val = WMGetFromPLString(value);
if (!val)
return 0;
if (sscanf(val, "0x%04X", &n) != 1)
return 0;
return n;
}
static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
{
WScreen *scr = wwin->screen_ptr;
@@ -174,7 +192,7 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
unsigned mask;
char *class, *instance, *command = NULL, buffer[512];
WMPropList *win_state, *cmd, *name, *workspace;
WMPropList *shaded, *miniaturized, *hidden, *geometry;
WMPropList *shaded, *miniaturized, *maximized, *hidden, *geometry;
WMPropList *dock, *shortcut;
if (wwin->orig_main_window != None && wwin->orig_main_window != wwin->client_win)
@@ -183,8 +201,13 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
win = wwin->client_win;
command = GetCommandForWindow(win);
if (!command)
return NULL;
if (!command) {
if (wapp->app_icon && wapp->app_icon->command) {
command = wmalloc(strlen(wapp->app_icon->command));
strcpy(command, wapp->app_icon->command);
} else
return NULL;
}
if (PropGetWMClass(win, &class, &instance)) {
if (class && instance)
@@ -202,6 +225,8 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
shaded = wwin->flags.shaded ? sYes : sNo;
miniaturized = wwin->flags.miniaturized ? sYes : sNo;
snprintf(buffer, sizeof(buffer), "0x%04X", wwin->flags.maximized);
maximized = WMCreatePLString(buffer);
hidden = wwin->flags.hidden ? sYes : sNo;
snprintf(buffer, sizeof(buffer), "%ix%i+%i+%i",
wwin->client.width, wwin->client.height, wwin->frame_x, wwin->frame_y);
@@ -221,12 +246,14 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp)
sWorkspace, workspace,
sShaded, shaded,
sMiniaturized, miniaturized,
sMaximized, maximized,
sHidden, hidden,
sShortcutMask, shortcut, sGeometry, geometry, NULL);
WMReleasePropList(name);
WMReleasePropList(cmd);
WMReleasePropList(workspace);
WMReleasePropList(maximized);
WMReleasePropList(geometry);
WMReleasePropList(shortcut);
if (wapp && wapp->app_icon && wapp->app_icon->dock) {
@@ -403,6 +430,11 @@ static WSavedState *getWindowState(WScreen * scr, WMPropList * win_state)
if (value != NULL)
state->miniaturized = getBool(value);
value = WMGetFromPLDictionary(win_state, sMaximized);
if (value != NULL) {
state->maximized = getHex(value);
}
value = WMGetFromPLDictionary(win_state, sHidden);
if (value != NULL)
state->hidden = getBool(value);
+8 -5
View File
@@ -61,6 +61,7 @@ struct SwitchPanel {
WMFont *font;
WMColor *white;
WMColor *gray;
};
/* these values will be updated whenever the switch panel
@@ -154,11 +155,9 @@ static void changeImage(WSwitchPanel *panel, int idecks, int selected, Bool dim,
border_space + pos.y, back->width, back->height, 0, 0);
} else {
RColor color;
WMScreen *wscr = WMWidgetScreen(icon);
color.red = 255;
color.red = WMRedComponentOfColor(WMGrayColor(wscr)) >> 8;
color.green = WMGreenComponentOfColor(WMGrayColor(wscr)) >> 8;
color.blue = WMBlueComponentOfColor(WMGrayColor(wscr)) >> 8;
color.red = WMRedComponentOfColor(panel->gray) >> 8;
color.green = WMGreenComponentOfColor(panel->gray) >> 8;
color.blue = WMBlueComponentOfColor(panel->gray) >> 8;
RFillImage(back, &color);
}
@@ -454,6 +453,7 @@ WSwitchPanel *wInitSwitchPanel(WScreen *scr, WWindow *curwin, Bool class_only)
}
panel->white = WMWhiteColor(scr->wmscreen);
panel->gray = WMGrayColor(scr->wmscreen);
panel->font = WMBoldSystemFontOfSize(scr->wmscreen, WMScaleY(12));
panel->icons = WMCreateArray(count);
panel->images = WMCreateArray(count);
@@ -589,6 +589,9 @@ void wSwitchPanelDestroy(WSwitchPanel *panel)
if (panel->white)
WMReleaseColor(panel->white);
if (panel->gray)
WMReleaseColor(panel->gray);
wfree(panel);
}
+1 -1
View File
@@ -162,7 +162,7 @@ WTexSolid *wTextureMakeSolid(WScreen*, XColor*);
WTexGradient *wTextureMakeGradient(WScreen*, int, const RColor*, const RColor*);
WTexMGradient *wTextureMakeMGradient(WScreen*, int, RColor**);
WTexTGradient *wTextureMakeTGradient(WScreen*, int, const RColor*, const RColor*, const char *, int);
WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[], int, const RColor[]);
WTexIGradient *wTextureMakeIGradient(WScreen*, int, const RColor[2], int, const RColor[2]);
WTexPixmap *wTextureMakePixmap(WScreen *scr, int style, const char *pixmap_file,
XColor *color);
void wTextureDestroy(WScreen*, WTexture*);
+79 -27
View File
@@ -29,6 +29,9 @@
#ifdef KEEP_XKB_LOCK_STATUS
#include <X11/XKBlib.h>
#endif /* KEEP_XKB_LOCK_STATUS */
#ifdef USE_XRES
#include <X11/extensions/XRes.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -475,6 +478,41 @@ Bool wWindowObscuresWindow(WWindow *wwin, WWindow *obscured)
return True;
}
/* Get the corresponding Process Identification Number of the active window */
static pid_t getWindowPid(Window win)
{
pid_t pid = -1;
pid = wNETWMGetPidForWindow(win);
#ifdef USE_XRES
if (pid > 0)
return pid;
else {
XResClientIdSpec spec;
int status;
long i, num_ids = 0;
XResClientIdValue *client_ids = NULL;
spec.client = win;
spec.mask = XRES_CLIENT_ID_PID_MASK;
status = XResQueryClientIds(dpy, 1, &spec, &num_ids, &client_ids);
if (status != Success)
return -1;
for (i = 0; i < num_ids; i++) {
if (client_ids[i].spec.mask == XRES_CLIENT_ID_PID_MASK) {
pid = XResGetClientPid(&client_ids[i]);
break;
}
}
XResClientIdsDestroy(num_ids, client_ids);
}
#endif
return pid;
}
static void fixLeaderProperties(WWindow *wwin)
{
XClassHint *classHint;
@@ -487,7 +525,7 @@ static void fixLeaderProperties(WWindow *wwin)
classHint = XAllocClassHint();
clientHints = XGetWMHints(dpy, wwin->client_win);
pid = wNETWMGetPidForWindow(wwin->client_win);
pid = getWindowPid(wwin->client_win);
if (pid > 0)
haveCommand = GetCommandForPid(pid, &argv, &argc);
else
@@ -688,6 +726,9 @@ WWindow *wManageWindow(WScreen *scr, Window window)
XChangeWindowAttributes(dpy, window, CWEventMask | CWDontPropagate | CWSaveUnder, &attribs);
XSetWindowBorderWidth(dpy, window, 0);
if (wwin->wm_class != NULL && strcmp(wwin->wm_class, "DockApp") != 0)
wwin->flags.fullscreen_monitors[0] = -1;
/* get hints from GNUstep app */
if (wwin->wm_class != NULL && strcmp(wwin->wm_class, "GNUstep") == 0)
wwin->flags.is_gnustep = 1;
@@ -878,6 +919,9 @@ WWindow *wManageWindow(WScreen *scr, Window window)
if (win_state->state->miniaturized > 0 && !WFLAGP(wwin, no_miniaturizable))
wwin->flags.miniaturized = win_state->state->miniaturized;
if (win_state->state->maximized > 0)
wwin->flags.maximized = win_state->state->maximized;
if (!IS_OMNIPRESENT(wwin)) {
int w = wDefaultGetStartWorkspace(scr, wwin->wm_instance,
wwin->wm_class);
@@ -1691,9 +1735,8 @@ void wWindowSingleFocus(WWindow *wwin)
/* bring window back to visible area */
move = wScreenBringInside(scr, &x, &y, wwin->frame->core->width, wwin->frame->core->height);
if (move) {
if (move)
wWindowConfigure(wwin, x, y, wwin->client.width, wwin->client.height);
}
}
void wWindowFocusPrev(WWindow *wwin, Bool inSameWorkspace)
@@ -1857,9 +1900,21 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
int baseW = 0;
int baseH = 0;
/*
* X11 proto defines width and height as a CARD16
* if window size is guaranteed to fail, failsafe to a reasonable size
*/
if (width > USHRT_MAX && height > USHRT_MAX) {
width = 640;
height = 480;
return;
}
if (wwin->normal_hints) {
winc = wwin->normal_hints->width_inc;
hinc = wwin->normal_hints->height_inc;
if (!wwin->flags.maximized) {
winc = wwin->normal_hints->width_inc;
hinc = wwin->normal_hints->height_inc;
}
minW = wwin->normal_hints->min_width;
minH = wwin->normal_hints->min_height;
maxW = wwin->normal_hints->max_width;
@@ -1875,15 +1930,19 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
baseH = wwin->normal_hints->base_height;
}
/* trust the mins provided by the client but not the maxs */
if (width < minW)
width = minW;
if (height < minH)
height = minH;
if (width > maxW)
width = maxW;
if (height > maxH)
height = maxH;
/* if only one dimension is over the top, set a default 4/3 ratio */
if (width > maxW && height < maxH) {
width = height * 4 / 3;
} else {
if(height > maxH && width < maxW)
height = width * 3 / 4;
}
/* aspect ratio code borrowed from olwm */
if (minAX > 0) {
@@ -1922,15 +1981,17 @@ void wWindowConstrainSize(WWindow *wwin, unsigned int *nwidth, unsigned int *nhe
}
}
if (baseW != 0)
width = (((width - baseW) / winc) * winc) + baseW;
else
width = (((width - minW) / winc) * winc) + minW;
if (!wwin->flags.maximized) {
if (baseW != 0)
width = (((width - baseW) / winc) * winc) + baseW;
else
width = (((width - minW) / winc) * winc) + minW;
if (baseH != 0)
height = (((height - baseH) / hinc) * hinc) + baseH;
else
height = (((height - minH) / hinc) * hinc) + minH;
if (baseH != 0)
height = (((height - baseH) / hinc) * hinc) + baseH;
else
height = (((height - minH) / hinc) * hinc) + minH;
}
/* broken stupid apps may cause preposterous values for these.. */
if (width > 0)
@@ -2087,14 +2148,6 @@ void wWindowConfigure(WWindow *wwin, int req_x, int req_y, int req_width, int re
int synth_notify = False;
int resize;
/* if window size is guaranteed to fail - fix it to some reasonable
* defaults */
if (req_height > SHRT_MAX)
req_height = 480;
if (req_width > SHRT_MAX)
req_height = 640;
resize = (req_width != wwin->client.width || req_height != wwin->client.height);
/*
* if the window is being moved but not resized then
@@ -2649,7 +2702,7 @@ void wWindowUpdateGNUstepAttr(WWindow * wwin, GNUstepWMAttributes * attr)
}
WMagicNumber wWindowAddSavedState(const char *instance, const char *class,
const char *command, pid_t pid, WSavedState * state)
const char *command, pid_t pid, WSavedState *state)
{
WWindowState *wstate;
@@ -2884,7 +2937,6 @@ static void titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event)
}
/* maximize window */
if (dir != 0 && IS_RESIZABLE(wwin)) {
int ndir = dir ^ wwin->flags.maximized;
+2 -1
View File
@@ -254,6 +254,7 @@ typedef struct WWindow {
unsigned int maximized:7;
unsigned int old_maximized:7;
unsigned int fullscreen:1;
long fullscreen_monitors[4];
unsigned int omnipresent:1;
unsigned int semi_focused:1;
/* window type flags */
@@ -308,9 +309,9 @@ typedef struct WWindow {
typedef struct WSavedState {
int workspace;
int miniaturized;
int maximized;
int shaded;
int hidden;
int maximized;
int x; /* original geometry of the */
int y; /* window if it's maximized */
unsigned int w;
+52 -2
View File
@@ -77,6 +77,9 @@ static Atom net_wm_visible_name; /* TODO (unnecessary?) */
static Atom net_wm_icon_name;
static Atom net_wm_visible_icon_name; /* TODO (unnecessary?) */
static Atom net_wm_desktop;
#ifdef USE_XINERAMA
static Atom net_wm_fullscreen_monitors;
#endif
static Atom net_wm_window_type;
static Atom net_wm_window_type_desktop;
static Atom net_wm_window_type_dock;
@@ -161,6 +164,9 @@ static atomitem_t atomNames[] = {
{"_NET_WM_ICON_NAME", &net_wm_icon_name},
{"_NET_WM_VISIBLE_ICON_NAME", &net_wm_visible_icon_name},
{"_NET_WM_DESKTOP", &net_wm_desktop},
#ifdef USE_XINERAMA
{"_NET_WM_FULLSCREEN_MONITORS", &net_wm_fullscreen_monitors},
#endif
{"_NET_WM_WINDOW_TYPE", &net_wm_window_type},
{"_NET_WM_WINDOW_TYPE_DESKTOP", &net_wm_window_type_desktop},
{"_NET_WM_WINDOW_TYPE_DOCK", &net_wm_window_type_dock},
@@ -287,6 +293,9 @@ static void setSupportedHints(WScreen *scr)
atom[i++] = net_wm_moveresize;
#endif
atom[i++] = net_wm_desktop;
#ifdef USE_XINERAMA
atom[i++] = net_wm_fullscreen_monitors;
#endif
atom[i++] = net_wm_window_type;
atom[i++] = net_wm_window_type_desktop;
atom[i++] = net_wm_window_type_dock;
@@ -1027,6 +1036,9 @@ static void updateStateHint(WWindow *wwin, Bool changedWorkspace, Bool del)
{ /* changeable */
if (del) {
XDeleteProperty(dpy, wwin->client_win, net_wm_state);
#ifdef USE_XINERAMA
XDeleteProperty(dpy, wwin->client_win, net_wm_fullscreen_monitors);
#endif
} else {
Atom state[15]; /* nr of defined state atoms */
int i = 0;
@@ -1067,6 +1079,20 @@ static void updateStateHint(WWindow *wwin, Bool changedWorkspace, Bool del)
XChangeProperty(dpy, wwin->client_win, net_wm_state, XA_ATOM, 32,
PropModeReplace, (unsigned char *)state, i);
#ifdef USE_XINERAMA
if (wwin->flags.fullscreen && (wwin->flags.fullscreen_monitors[0] != -1)) {
unsigned long data[4];
data[0] = wwin->flags.fullscreen_monitors[0];
data[1] = wwin->flags.fullscreen_monitors[1];
data[2] = wwin->flags.fullscreen_monitors[2];
data[3] = wwin->flags.fullscreen_monitors[3];
XChangeProperty(dpy, wwin->client_win, net_wm_fullscreen_monitors, XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)data, 4);
}
#endif
}
}
@@ -1260,8 +1286,10 @@ static void doStateAtom(WWindow *wwin, Atom state, int set, Bool init)
} else {
if (set)
wFullscreenWindow(wwin);
else
else {
wUnfullscreenWindow(wwin);
wwin->flags.fullscreen_monitors[0] = -1;
}
}
} else if (state == net_wm_state_above) {
if (set == _NET_WM_STATE_TOGGLE)
@@ -1759,8 +1787,30 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent *event)
wWindowChangeWorkspace(wwin, desktop);
}
return True;
}
#ifdef USE_XINERAMA
} else if (event->message_type == net_wm_fullscreen_monitors) {
unsigned long top, bottom, left, right, src_indication;
top = event->data.l[0];
bottom = event->data.l[1];
left = event->data.l[2];
right = event->data.l[3];
src_indication = event->data.l[4];
if (src_indication > 1)
wwarning("_NET_WM_FULLSCREEN_MONITORS source indication %ld not supported", src_indication);
wFullscreenMonitorsWindow(wwin, top, bottom, left, right);
return True;
}
#else
}
#endif
#ifdef DEBUG_WMSPEC
wmessage("processClientMessage unsupported type %s", XGetAtomName(dpy, event->message_type));
#endif
return False;
}
+6 -6
View File
@@ -337,9 +337,9 @@ static WMPixmap *get_mini_workspace(WWorkspaceMap *wsmap, int index)
static void create_mini_workspace(WScreen *scr, WWorkspaceMap *wsmap, W_WorkspaceMap *wsmap_array)
{
int workspace_index;
unsigned short workspace_index;
int mini_workspace_cnt;
char name[10];
char name[6];
WMButton *mini_workspace_btn;
WMPixmap *icon;
@@ -363,7 +363,7 @@ static void create_mini_workspace(WScreen *scr, WWorkspaceMap *wsmap, W_Workspac
WMReleasePixmap(icon);
}
snprintf(name, sizeof(name), "%d", workspace_index);
snprintf(name, sizeof(name), "%hu", workspace_index);
WMSetButtonText(mini_workspace_btn, name);
WMSetButtonAction(mini_workspace_btn, selected_workspace_callback, wsmap);
}
@@ -423,9 +423,9 @@ static WWorkspaceMap *create_workspace_map(WScreen *scr, W_WorkspaceMap *wsmap_a
static void update_mini_workspace(WWorkspaceMap *wsmap, W_WorkspaceMap *wsmap_array, int bulk_of_ten)
{
int local_index, general_index;
unsigned short local_index, general_index;
int mini_workspace_cnt;
char name[10];
char name[6];
WMPixmap *icon;
if (bulk_of_ten == wsmap_bulk_index)
@@ -448,7 +448,7 @@ static void update_mini_workspace(WWorkspaceMap *wsmap, W_WorkspaceMap *wsmap_ar
if (general_index < wsmap->scr->workspace_count) {
/* updating label */
WMSetLabelText(wsmap_array[local_index].workspace_label, wsmap->scr->workspaces[general_index]->name);
snprintf(name, sizeof(name), "%d", general_index);
snprintf(name, sizeof(name), "%hu", general_index);
WMSetButtonText(wsmap_array[local_index].workspace_img_button, name);
/* updating label background*/
+30
View File
@@ -410,3 +410,33 @@ WMPoint wGetPointToCenterRectInHead(WScreen * scr, int head, int width, int heig
return p;
}
/* Find the bounding rect of the union of two rectangles */
void wGetRectUnion(const WMRect *rect1, const WMRect *rect2, WMRect *dest)
{
int dest_x, dest_y;
int dest_w, dest_h;
dest_x = rect1->pos.x;
dest_y = rect1->pos.y;
dest_w = rect1->size.width;
dest_h = rect1->size.height;
if (rect2->pos.x < dest_x) {
dest_w += dest_x - rect2->pos.x;
dest_x = rect2->pos.x;
}
if (rect2->pos.y < dest_y) {
dest_h += dest_y - rect2->pos.y;
dest_y = rect2->pos.y;
}
if (rect2->pos.x + rect2->size.width > dest_x + dest_w)
dest_w = rect2->pos.x + rect2->size.width - dest_x;
if (rect2->pos.y + rect2->size.height > dest_y + dest_h)
dest_h = rect2->pos.y + rect2->size.height - dest_y;
dest->pos.x = dest_x;
dest->pos.y = dest_y;
dest->size.width = dest_w;
dest->size.height = dest_h;
}
+2
View File
@@ -60,6 +60,8 @@ WArea wGetUsableAreaForHead(WScreen *scr, int head, WArea *totalAreaPtr, Bool no
WMPoint wGetPointToCenterRectInHead(WScreen *scr, int head, int width, int height);
void wGetRectUnion(const WMRect *rect1, const WMRect *rect2, WMRect *dest);
Bool wWindowTouchesHead(WWindow *wwin, int head);
Bool wAppIconTouchesHead(WAppIcon *aicon, int head);
+2 -1
View File
@@ -36,6 +36,7 @@ Perpetrator: Sudish Joseph <sj@eng.mindspring.net>, Sept. 1997. */
#include <X11/XKBlib.h>
#include <WINGs/WUtil.h>
#include <WINGs/WINGsP.h>
#include "WindowMaker.h"
#include "xmodifier.h"
@@ -174,7 +175,7 @@ static void x_reset_modifier_mapping(Display * display)
}
code = x_modifier_keymap->modifiermap[modifier_index * mkpm + modifier_key];
sym = (code ? XkbKeycodeToKeysym(display, code, 0, column) : NoSymbol);
sym = (code ? W_KeycodeToKeysym(display, code, column) : NoSymbol);
if (sym == last_sym)
continue;
+5 -2
View File
@@ -70,10 +70,13 @@ wmmenugen_SOURCES = wmmenugen.c wmmenugen.h wmmenugen_misc.c \
wmmenugen_parse_wmconfig.c \
wmmenugen_parse_xdg.c
wmiv_CFLAGS = @PANGO_CFLAGS@ @PTHREAD_CFLAGS@
wmiv_LDADD = \
$(top_builddir)/wrlib/libwraster.la \
@XLFLAGS@ @XLIBS@ \
@GFXLIBS@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(LIBEXIF)
$(top_builddir)/WINGs/libWINGs.la \
@XLFLAGS@ @XLIBS@ @GFXLIBS@ \
@PANGO_LIBS@ @PTHREAD_LIBS@ @LIBEXIF@
wmiv_SOURCES = wmiv.c wmiv.h
+4 -5
View File
@@ -22,11 +22,10 @@
#define _GNU_SOURCE
#endif
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include "wraster.h"
#include <WINGs/WINGsP.h>
#include <wraster.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -750,7 +749,7 @@ int main(int argc, char **argv)
dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "Error: can't open display");
fprintf(stderr, "Error: can't open display\n");
linked_list_free(&list);
return EXIT_FAILURE;
}
@@ -932,7 +931,7 @@ int main(int argc, char **argv)
continue;
}
if (e.type == KeyPress) {
keysym = XkbKeycodeToKeysym(dpy, e.xkey.keycode, 0, e.xkey.state & ShiftMask?1:0);
keysym = W_KeycodeToKeysym(dpy, e.xkey.keycode, e.xkey.state & ShiftMask?1:0);
#ifdef HAVE_PTHREAD
if (keysym != XK_Right)
diaporama_flag = False;
+74 -69
View File
@@ -95,19 +95,13 @@ static noreturn void my_error_exit(j_common_ptr cinfo)
longjmp(myerr->setjmp_buffer, 1);
}
RImage *RLoadJPEG(const char *file_name)
static RImage *do_read_jpeg_file(struct jpeg_decompress_struct *cinfo, const char *file_name)
{
RImage *image = NULL;
struct jpeg_decompress_struct cinfo;
int i;
unsigned char *ptr;
JSAMPROW buffer[1], bptr;
FILE *file;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
* struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
file = fopen(file_name, "rb");
if (!file) {
@@ -115,6 +109,78 @@ RImage *RLoadJPEG(const char *file_name)
return NULL;
}
jpeg_create_decompress(cinfo);
jpeg_stdio_src(cinfo, file);
jpeg_read_header(cinfo, TRUE);
if (cinfo->image_width < 1 || cinfo->image_height < 1) {
buffer[0] = NULL; /* Initialize pointer to avoid spurious free in cleanup code */
RErrorCode = RERR_BADIMAGEFILE;
goto abort_and_release_resources;
}
buffer[0] = (JSAMPROW) malloc(cinfo->image_width * cinfo->num_components);
if (!buffer[0]) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
if (cinfo->jpeg_color_space == JCS_GRAYSCALE)
cinfo->out_color_space = JCS_GRAYSCALE;
else
cinfo->out_color_space = JCS_RGB;
cinfo->quantize_colors = FALSE;
cinfo->do_fancy_upsampling = FALSE;
cinfo->do_block_smoothing = FALSE;
jpeg_calc_output_dimensions(cinfo);
image = RCreateImage(cinfo->image_width, cinfo->image_height, False);
if (!image) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
jpeg_start_decompress(cinfo);
ptr = image->data;
if (cinfo->out_color_space == JCS_RGB) {
while (cinfo->output_scanline < cinfo->output_height) {
jpeg_read_scanlines(cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
memcpy(ptr, bptr, cinfo->image_width * 3);
ptr += cinfo->image_width * 3;
}
} else {
while (cinfo->output_scanline < cinfo->output_height) {
jpeg_read_scanlines(cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
for (i = 0; i < cinfo->image_width; i++) {
*ptr++ = *bptr;
*ptr++ = *bptr;
*ptr++ = *bptr++;
}
}
}
jpeg_finish_decompress(cinfo);
abort_and_release_resources:
jpeg_destroy_decompress(cinfo);
fclose(file);
if (buffer[0])
free(buffer[0]);
return image;
}
RImage *RLoadJPEG(const char *file_name)
{
struct jpeg_decompress_struct cinfo;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main
* JPEG parameter struct, to avoid dangling-pointer problems.
*/
struct my_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
@@ -124,68 +190,7 @@ RImage *RLoadJPEG(const char *file_name)
* We need to clean up the JPEG object, close the input file, and return.
*/
jpeg_destroy_decompress(&cinfo);
fclose(file);
return NULL;
}
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, file);
jpeg_read_header(&cinfo, TRUE);
if (cinfo.image_width < 1 || cinfo.image_height < 1) {
buffer[0] = NULL; /* Initialize pointer to avoid spurious free in cleanup code */
RErrorCode = RERR_BADIMAGEFILE;
goto abort_and_release_resources;
}
buffer[0] = (JSAMPROW) malloc(cinfo.image_width * cinfo.num_components);
if (!buffer[0]) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
cinfo.out_color_space = JCS_GRAYSCALE;
else
cinfo.out_color_space = JCS_RGB;
cinfo.quantize_colors = FALSE;
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_calc_output_dimensions(&cinfo);
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
if (!image) {
RErrorCode = RERR_NOMEMORY;
goto abort_and_release_resources;
}
jpeg_start_decompress(&cinfo);
ptr = image->data;
if (cinfo.out_color_space == JCS_RGB) {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
memcpy(ptr, bptr, cinfo.image_width * 3);
ptr += cinfo.image_width * 3;
}
} else {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer, (JDIMENSION) 1);
bptr = buffer[0];
for (i = 0; i < cinfo.image_width; i++) {
*ptr++ = *bptr;
*ptr++ = *bptr;
*ptr++ = *bptr++;
}
}
}
jpeg_finish_decompress(&cinfo);
abort_and_release_resources:
jpeg_destroy_decompress(&cinfo);
fclose(file);
if (buffer[0])
free(buffer[0]);
return image;
return do_read_jpeg_file(&cinfo, file_name);
}
+15 -5
View File
@@ -28,6 +28,7 @@
#include <tiff.h>
#include <tiffio.h>
#include <tiffvers.h>
#include "wraster.h"
#include "imgformat.h"
@@ -38,14 +39,19 @@ RImage *RLoadTIFF(const char *file, int index)
{
RImage *image = NULL;
TIFF *tif;
int i;
int i, ch;
unsigned char *r, *g, *b, *a;
uint16 alpha, amode;
#if TIFFLIB_VERSION < 20210416
uint16 alpha, amode, extrasamples;
uint16 *sampleinfo;
uint32 width, height;
uint32 *data, *ptr;
uint16 extrasamples;
uint16 *sampleinfo;
int ch;
#else
uint16_t alpha, amode, extrasamples;;
uint16_t *sampleinfo;
uint32_t width, height;
uint32_t *data, *ptr;
#endif
tif = TIFFOpen(file, "r");
if (!tif)
@@ -79,7 +85,11 @@ RImage *RLoadTIFF(const char *file, int index)
}
/* read data */
#if TIFFLIB_VERSION < 20210416
ptr = data = (uint32 *) _TIFFmalloc(width * height * sizeof(uint32));
#else
ptr = data = (uint32_t *) _TIFFmalloc(width * height * sizeof(uint32_t));
#endif
if (!data) {
RErrorCode = RERR_NOMEMORY;