mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-24 23:22:30 +01:00
Bug fixes for 0.20.3 pre-release 2
This commit is contained in:
@@ -102,16 +102,16 @@ CPPFLAGS = \
|
||||
|
||||
|
||||
INCLUDES = \
|
||||
@XCFLAGS@ \
|
||||
-I$(top_srcdir)/libPropList \
|
||||
-I$(top_srcdir)/wrlib \
|
||||
-I$(top_srcdir)/WINGs
|
||||
-I$(top_srcdir)/WINGs @XCFLAGS@
|
||||
|
||||
|
||||
wmaker_LDADD = \
|
||||
-L$(top_builddir)/WINGs -lWINGs\
|
||||
-L$(top_builddir)/wrlib -lwraster\
|
||||
-L$(top_builddir)/libPropList -lPropList\
|
||||
@GFXLFLAGS@ \
|
||||
@XLFLAGS@ \
|
||||
@GFXLIBS@ \
|
||||
@XLIBS@ \
|
||||
|
||||
@@ -63,6 +63,7 @@ CC = @CC@
|
||||
CPP_PATH = @CPP_PATH@
|
||||
DFLAGS = @DFLAGS@
|
||||
GFXFLAGS = @GFXFLAGS@
|
||||
GFXLFLAGS = @GFXLFLAGS@
|
||||
GFXLIBS = @GFXLIBS@
|
||||
I18N = @I18N@
|
||||
I18N_MB = @I18N_MB@
|
||||
@@ -191,15 +192,15 @@ CPPFLAGS = \
|
||||
-DPIXMAPDIR="\"$(pixmapdir)\""
|
||||
|
||||
INCLUDES = \
|
||||
@XCFLAGS@ \
|
||||
-I$(top_srcdir)/libPropList \
|
||||
-I$(top_srcdir)/wrlib \
|
||||
-I$(top_srcdir)/WINGs
|
||||
-I$(top_srcdir)/WINGs @XCFLAGS@
|
||||
|
||||
wmaker_LDADD = \
|
||||
-L$(top_builddir)/WINGs -lWINGs\
|
||||
-L$(top_builddir)/wrlib -lwraster\
|
||||
-L$(top_builddir)/libPropList -lPropList\
|
||||
@GFXLFLAGS@ \
|
||||
@XLFLAGS@ \
|
||||
@GFXLIBS@ \
|
||||
@XLIBS@ \
|
||||
|
||||
@@ -223,6 +223,10 @@ typedef struct WPreferences {
|
||||
* of their owners */
|
||||
char title_justification; /* titlebar text alignment */
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
char modelock;
|
||||
#endif
|
||||
|
||||
char no_dithering; /* use dithering or not */
|
||||
|
||||
char no_sound; /* enable/disable sound */
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "dock.h"
|
||||
#include "appmenu.h"
|
||||
#include "winspector.h"
|
||||
#include "list.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#ifdef WMSOUND
|
||||
#include "wmsound.h"
|
||||
@@ -273,14 +275,15 @@ wShadeWindow(WWindow *wwin)
|
||||
while (h>wwin->frame->top_width+1) {
|
||||
XMoveWindow(dpy, wwin->client_win, 0, y);
|
||||
XResizeWindow(dpy, wwin->frame->core->window, w, h);
|
||||
XSync(dpy, 0);
|
||||
XFlush(dpy);
|
||||
|
||||
if (time(NULL)-time0 > MAX_ANIMATION_TIME)
|
||||
break;
|
||||
|
||||
if (SHADE_DELAY > 0)
|
||||
wusleep(SHADE_DELAY*1000L);
|
||||
h-=s;
|
||||
y-=s;
|
||||
|
||||
if (time(NULL)-time0 > MAX_ANIMATION_TIME)
|
||||
break;
|
||||
}
|
||||
XMoveWindow(dpy, wwin->client_win, 0, wwin->frame->top_width);
|
||||
}
|
||||
@@ -300,7 +303,9 @@ wShadeWindow(WWindow *wwin)
|
||||
/* for the client it's just like iconification */
|
||||
wFrameWindowResize(wwin->frame, wwin->frame->core->width,
|
||||
wwin->frame->top_width-1);
|
||||
/*
|
||||
wClientSetState(wwin, IconicState, None);
|
||||
*/
|
||||
|
||||
/* update window list to reflect shaded state */
|
||||
UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_STATE);
|
||||
@@ -368,8 +373,9 @@ wUnshadeWindow(WWindow *wwin)
|
||||
wFrameWindowResize(wwin->frame, wwin->frame->core->width,
|
||||
wwin->frame->top_width + wwin->client.height
|
||||
+ wwin->frame->bottom_width);
|
||||
|
||||
/*
|
||||
wClientSetState(wwin, NormalState, None);
|
||||
*/
|
||||
/* if the window is focused, set the focus again as it was disabled during
|
||||
* shading */
|
||||
if (wwin->flags.focused)
|
||||
@@ -1592,3 +1598,37 @@ wArrangeIcons(WScreen *scr, Bool arrangeAll)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wSelectWindow(WWindow *wwin, Bool flag)
|
||||
{
|
||||
WScreen *scr = wwin->screen_ptr;
|
||||
if (flag) {
|
||||
wwin->flags.selected = 1;
|
||||
XSetWindowBorder(dpy, wwin->frame->core->window, scr->white_pixel);
|
||||
scr->selected_windows = list_cons(wwin, scr->selected_windows);
|
||||
} else {
|
||||
wwin->flags.selected = 0;
|
||||
XSetWindowBorder(dpy, wwin->frame->core->window,
|
||||
scr->frame_border_pixel);
|
||||
scr->selected_windows = list_remove_elem(scr->selected_windows, wwin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wMakeWindowVisible(WWindow *wwin)
|
||||
{
|
||||
wWorkspaceChange(wwin->screen_ptr, wwin->frame->workspace);
|
||||
|
||||
if (wwin->flags.shaded) {
|
||||
wUnshadeWindow(wwin);
|
||||
}
|
||||
if (wwin->flags.hidden) {
|
||||
wUnhideApplication(wApplicationOf(wwin->main_window), False, False);
|
||||
} else if (wwin->flags.miniaturized) {
|
||||
wDeiconifyWindow(wwin);
|
||||
} else {
|
||||
wSetFocusTo(wwin->screen_ptr, wwin);
|
||||
wRaiseFrame(wwin->frame->core);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ void wIconifyWindow(WWindow *wwin);
|
||||
void wDeiconifyWindow(WWindow *wwin);
|
||||
|
||||
void wSelectWindows(WScreen *scr, XEvent *ev);
|
||||
void wSelectWindow(WWindow *wwin);
|
||||
void wUnselectWindows();
|
||||
void wSelectWindow(WWindow *wwin, Bool flag);
|
||||
void wUnselectWindows(WScreen *scr);
|
||||
|
||||
void wMaximizeWindow(WWindow *wwin, int directions);
|
||||
void wUnmaximizeWindow(WWindow *wwin);
|
||||
@@ -58,6 +58,6 @@ void wRefreshDesktop(WScreen *scr);
|
||||
|
||||
void wArrangeIcons(WScreen *scr, Bool arrangeAll);
|
||||
|
||||
|
||||
void wMakeWindowVisible(WWindow *wwin);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -137,8 +137,7 @@ makePixmap(WScreen *scr, int width, int height, int side, Pixmap *mask)
|
||||
if (!bal->monoGC) {
|
||||
bal->monoGC = XCreateGC(dpy, bitmap, 0, NULL);
|
||||
}
|
||||
XSetForeground(dpy, bal->monoGC,
|
||||
BlackPixelOfScreen(ScreenOfDisplay(dpy, scr->screen)));
|
||||
XSetForeground(dpy, bal->monoGC, 0);
|
||||
XFillRectangle(dpy, bitmap, bal->monoGC, 0, 0, width+SPACE, height+SPACE);
|
||||
|
||||
pixmap = XCreatePixmap(dpy, scr->root_win, width+SPACE, height+SPACE,
|
||||
@@ -153,8 +152,7 @@ makePixmap(WScreen *scr, int width, int height, int side, Pixmap *mask)
|
||||
}
|
||||
x = 0;
|
||||
|
||||
XSetForeground(dpy, bal->monoGC,
|
||||
WhitePixelOfScreen(ScreenOfDisplay(dpy, scr->screen)));
|
||||
XSetForeground(dpy, bal->monoGC, 1);
|
||||
drawBalloon(bitmap, bal->monoGC, x, y, width, height, side);
|
||||
XSetForeground(dpy, scr->draw_gc, scr->white_pixel);
|
||||
drawBalloon(pixmap, scr->draw_gc, x+1, y+1, width-2, height-2, side);
|
||||
|
||||
17
src/client.c
17
src/client.c
@@ -73,8 +73,9 @@ extern Bool wShapeSupported;
|
||||
void
|
||||
wClientRestore(WWindow *wwin)
|
||||
{
|
||||
#if 0
|
||||
int gx, gy;
|
||||
|
||||
|
||||
wClientGetGravityOffsets(wwin, &gx, &gy);
|
||||
/* set the positio of the frame on screen */
|
||||
wwin->frame_x -= gx * FRAME_BORDER_WIDTH;
|
||||
@@ -82,7 +83,7 @@ wClientRestore(WWindow *wwin)
|
||||
/* if gravity is to the south, account for the border sizes */
|
||||
if (gy > 0)
|
||||
wwin->frame_y += (wwin->frame->top_width + wwin->frame->bottom_width);
|
||||
|
||||
#endif
|
||||
XUnmapWindow(dpy, wwin->client_win);
|
||||
XSetWindowBorderWidth(dpy, wwin->client_win, wwin->old_border_width);
|
||||
XReparentWindow(dpy, wwin->client_win, wwin->screen_ptr->root_win,
|
||||
@@ -232,12 +233,12 @@ wClientConfigure(WWindow *wwin, XConfigureRequestEvent *xcre)
|
||||
if (!wwin->flags.shaded) {
|
||||
/* If the window is shaded, wrong height will be set for the window */
|
||||
if (xcre->value_mask & CWX)
|
||||
nx = xcre->x - FRAME_BORDER_WIDTH;
|
||||
nx = xcre->x;
|
||||
else
|
||||
nx = wwin->frame_x;
|
||||
|
||||
if (xcre->value_mask & CWY)
|
||||
ny = xcre->y - FRAME_BORDER_WIDTH - ((ofs_y < 0) ? 0 : wwin->frame->top_width);
|
||||
ny = xcre->y - ((ofs_y < 0) ? 0 : wwin->frame->top_width);
|
||||
else
|
||||
ny = wwin->frame_y;
|
||||
|
||||
@@ -708,8 +709,12 @@ GetColormapWindows(WWindow *wwin)
|
||||
if (wwin->cmap_windows) {
|
||||
XFree(wwin->cmap_windows);
|
||||
}
|
||||
if (!XGetWMColormapWindows(dpy, wwin->client_win, &(wwin->cmap_windows),
|
||||
&(wwin->cmap_window_no))) {
|
||||
|
||||
wwin->cmap_windows = NULL;
|
||||
wwin->cmap_window_no = 0;
|
||||
|
||||
if (XGetWMColormapWindows(dpy, wwin->client_win, &(wwin->cmap_windows),
|
||||
&(wwin->cmap_window_no))!=Success) {
|
||||
wwin->cmap_window_no = 0;
|
||||
wwin->cmap_windows = NULL;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,13 @@ wColormapInstallForWindow(WScreen *scr, WWindow *wwin)
|
||||
|
||||
if (scr->current_colormap != attributes.colormap) {
|
||||
scr->current_colormap = attributes.colormap;
|
||||
XInstallColormap(dpy, attributes.colormap);
|
||||
/*
|
||||
* ICCCM 2.0: some client requested permission
|
||||
* to install colormaps by itself and we granted.
|
||||
* So, we can't install any colormaps.
|
||||
*/
|
||||
if (!scr->flags.colormap_stuff_blocked)
|
||||
XInstallColormap(dpy, attributes.colormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,9 +87,11 @@ wColormapInstallForWindow(WScreen *scr, WWindow *wwin)
|
||||
|
||||
if (scr->current_colormap != attributes.colormap) {
|
||||
scr->current_colormap = attributes.colormap;
|
||||
XInstallColormap(dpy, attributes.colormap);
|
||||
if (!scr->flags.colormap_stuff_blocked)
|
||||
XInstallColormap(dpy, attributes.colormap);
|
||||
}
|
||||
}
|
||||
XSync(dpy, False);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,3 +118,18 @@ wColormapUninstallRoot(WScreen *scr)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wColormapAllowClientInstallation(WScreen *scr, Bool starting)
|
||||
{
|
||||
scr->flags.colormap_stuff_blocked = starting;
|
||||
/*
|
||||
* Client stopped managing the colormap stuff. Restore the colormap
|
||||
* that would be installed if the client did not request colormap
|
||||
* stuff.
|
||||
*/
|
||||
if (!starting) {
|
||||
XInstallColormap(dpy, scr->current_colormap);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#define PACKAGE "WindowMaker"
|
||||
|
||||
/* package version */
|
||||
#define VERSION "0.20.2"
|
||||
#define VERSION "0.20.3"
|
||||
|
||||
/* Define if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
@@ -596,7 +596,27 @@ WDefaultEntry optionList[] = {
|
||||
},
|
||||
{"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
|
||||
NULL, getKeybind, setKeyGrab
|
||||
},
|
||||
{"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
|
||||
NULL, getKeybind, setKeyGrab
|
||||
},
|
||||
{"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
|
||||
NULL, getKeybind, setKeyGrab
|
||||
},
|
||||
{"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
|
||||
NULL, getKeybind, setKeyGrab
|
||||
},
|
||||
{"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
|
||||
NULL, getKeybind, setKeyGrab
|
||||
},
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
|
||||
NULL, getKeybind, setKeyGrab
|
||||
},
|
||||
{"KbdModeLock", "NO", NULL,
|
||||
&wPreferences.modelock, getBool, NULL
|
||||
}
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
};
|
||||
|
||||
|
||||
|
||||
28
src/dock.c
28
src/dock.c
@@ -947,7 +947,7 @@ makeClipOptionsMenu(WScreen *scr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry = wMenuAddCallback(menu, _("Keep Clip On Top"),
|
||||
entry = wMenuAddCallback(menu, _("Keep on top"),
|
||||
toggleLoweredCallback, NULL);
|
||||
entry->flags.indicator = 1;
|
||||
entry->flags.indicator_on = 1;
|
||||
@@ -995,7 +995,7 @@ dockMenuCreate(WScreen *scr, int type)
|
||||
|
||||
menu = wMenuCreate(scr, NULL, False);
|
||||
if (type != WM_CLIP) {
|
||||
entry = wMenuAddCallback(menu, _("Keep Dock On Top"),
|
||||
entry = wMenuAddCallback(menu, _("Keep on top"),
|
||||
toggleLoweredCallback, NULL);
|
||||
entry->flags.indicator = 1;
|
||||
entry->flags.indicator_on = 1;
|
||||
@@ -1194,8 +1194,8 @@ make_icon_state(WAppIcon *btn)
|
||||
{
|
||||
proplist_t node = NULL;
|
||||
proplist_t command, autolaunch, name, forced, host, position, buggy;
|
||||
char buffer[256];
|
||||
|
||||
char *tmp;
|
||||
char buffer[64];
|
||||
|
||||
if (btn) {
|
||||
if (!btn->command)
|
||||
@@ -1205,16 +1205,11 @@ make_icon_state(WAppIcon *btn)
|
||||
|
||||
autolaunch = btn->auto_launch ? dYes : dNo;
|
||||
|
||||
if (btn->wm_class && btn->wm_instance)
|
||||
sprintf(buffer, "%s.%s", btn->wm_instance, btn->wm_class);
|
||||
else if (btn->wm_instance)
|
||||
sprintf(buffer, "%s", btn->wm_instance);
|
||||
else if (btn->wm_class)
|
||||
sprintf(buffer, ".%s", btn->wm_class);
|
||||
else
|
||||
sprintf(buffer, ".");
|
||||
tmp = EscapeWM_CLASS(btn->wm_instance, btn->wm_class);
|
||||
|
||||
name = PLMakeString(buffer);
|
||||
name = PLMakeString(tmp);
|
||||
|
||||
free(tmp);
|
||||
|
||||
forced = btn->forced_dock ? dYes : dNo;
|
||||
|
||||
@@ -1371,7 +1366,10 @@ restore_icon_state(WScreen *scr, proplist_t info, int type, int index)
|
||||
|
||||
/* get commands */
|
||||
|
||||
command = wstrdup(PLGetString(cmd));
|
||||
if (cmd)
|
||||
command = wstrdup(PLGetString(cmd));
|
||||
else
|
||||
command = NULL;
|
||||
|
||||
if (!command || strcmp(command, "-")==0) {
|
||||
if (command)
|
||||
@@ -3724,7 +3722,7 @@ showClipBalloon(WDock *dock, int workspace)
|
||||
|
||||
text = scr->workspaces[workspace]->name;
|
||||
|
||||
w = wTextWidth(scr->clip_title_font->font, text, strlen(text)) + 4;
|
||||
w = wTextWidth(scr->clip_title_font->font, text, strlen(text));
|
||||
|
||||
h = scr->clip_title_font->height;
|
||||
XResizeWindow(dpy, scr->clip_balloon, w, h);
|
||||
|
||||
107
src/event.c
107
src/event.c
@@ -39,6 +39,9 @@
|
||||
#include <gdk/gdk.h>
|
||||
#endif
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
#include <X11/XKBlib.h>
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
|
||||
#include "WindowMaker.h"
|
||||
#include "window.h"
|
||||
@@ -70,6 +73,8 @@ extern WPreferences wPreferences;
|
||||
|
||||
#define MOD_MASK wPreferences.modifier_mask
|
||||
|
||||
extern Atom _XA_WM_COLORMAP_NOTIFY;
|
||||
|
||||
extern Atom _XA_WM_CHANGE_STATE;
|
||||
extern Atom _XA_WM_DELETE_WINDOW;
|
||||
extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
|
||||
@@ -116,6 +121,7 @@ static void handleClientMessage();
|
||||
static void handleKeyPress();
|
||||
static void handleFocusIn();
|
||||
static void handleMotionNotify();
|
||||
|
||||
#ifdef SHAPE
|
||||
static void handleShapeNotify();
|
||||
#endif
|
||||
@@ -148,7 +154,7 @@ static DeathHandler *deathHandler=NULL;
|
||||
|
||||
|
||||
|
||||
WDeathHandlerID
|
||||
WMagicNumber
|
||||
wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata)
|
||||
{
|
||||
DeathHandler *handler;
|
||||
@@ -171,7 +177,7 @@ wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata)
|
||||
|
||||
|
||||
void
|
||||
wDeleteDeathHandler(WDeathHandlerID id)
|
||||
wDeleteDeathHandler(WMagicNumber id)
|
||||
{
|
||||
DeathHandler *tmp, *handler=(DeathHandler*)id;
|
||||
|
||||
@@ -259,7 +265,7 @@ DispatchEvent(XEvent *event)
|
||||
case ConfigureRequest:
|
||||
handleConfigureRequest(event);
|
||||
break;
|
||||
|
||||
|
||||
case DestroyNotify:
|
||||
handleDestroyNotify(event->xdestroywindow.window);
|
||||
break;
|
||||
@@ -271,7 +277,7 @@ DispatchEvent(XEvent *event)
|
||||
case UnmapNotify:
|
||||
handleUnmapNotify(event);
|
||||
break;
|
||||
|
||||
|
||||
case ButtonPress:
|
||||
handleButtonPress(event);
|
||||
break;
|
||||
@@ -522,8 +528,6 @@ handleMapRequest(XEvent *ev)
|
||||
if (state==WithdrawnState) {
|
||||
wwin->flags.mapped = 0;
|
||||
wClientSetState(wwin, WithdrawnState, None);
|
||||
XSelectInput(dpy, wwin->client_win, NoEventMask);
|
||||
XRemoveFromSaveSet(dpy, wwin->client_win);
|
||||
wUnmanageWindow(wwin, True);
|
||||
} else {
|
||||
wClientSetState(wwin, NormalState, None);
|
||||
@@ -549,32 +553,6 @@ handleMapRequest(XEvent *ev)
|
||||
wwin->flags.ignore_next_unmap = 1;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
switch (state) {
|
||||
case WithdrawnState:
|
||||
wwin->flags.mapped = 0;
|
||||
wClientSetState(wwin, WithdrawnState, None);
|
||||
XSelectInput(dpy, wwin->client_win, NoEventMask);
|
||||
XRemoveFromSaveSet(dpy, wwin->client_win);
|
||||
wUnmanageWindow(wwin, True);
|
||||
break;
|
||||
|
||||
case IconicState:
|
||||
if (!wwin->flags.miniaturized) {
|
||||
wwin->flags.ignore_next_unmap=1;
|
||||
wwin->flags.skip_next_animation=1;
|
||||
wIconifyWindow(wwin);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case DontCareState:
|
||||
case NormalState:
|
||||
*/
|
||||
default:
|
||||
wClientSetState(wwin, NormalState, None);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +652,7 @@ handleButtonPress(XEvent *event)
|
||||
}
|
||||
} else if (event->xbutton.button==wPreferences.select_button) {
|
||||
|
||||
wUnselectWindows();
|
||||
wUnselectWindows(scr);
|
||||
wSelectWindows(scr, event);
|
||||
}
|
||||
}
|
||||
@@ -782,12 +760,19 @@ handleUnmapNotify(XEvent *event)
|
||||
if (XCheckTypedWindowEvent(dpy, wwin->client_win, DestroyNotify,&ev)) {
|
||||
DispatchEvent(&ev);
|
||||
} else {
|
||||
Bool reparented = False;
|
||||
|
||||
if (XCheckTypedWindowEvent(dpy, wwin->client_win, ReparentNotify, &ev))
|
||||
reparented = True;
|
||||
|
||||
/* withdraw window */
|
||||
wwin->flags.mapped = 0;
|
||||
XSelectInput(dpy, wwin->client_win, NoEventMask);
|
||||
XRemoveFromSaveSet(dpy, wwin->client_win);
|
||||
wClientSetState(wwin, WithdrawnState, None);
|
||||
wUnmanageWindow(wwin, True);
|
||||
if (!reparented)
|
||||
wClientSetState(wwin, WithdrawnState, None);
|
||||
|
||||
/* if the window was reparented, do not reparent it back to the
|
||||
* root window */
|
||||
wUnmanageWindow(wwin, !reparented);
|
||||
}
|
||||
XUngrabServer(dpy);
|
||||
}
|
||||
@@ -856,6 +841,18 @@ handleClientMessage(XEvent *event)
|
||||
if (!wwin) return;
|
||||
if (!wwin->flags.miniaturized)
|
||||
wIconifyWindow(wwin);
|
||||
} else if (event->xclient.message_type == _XA_WM_COLORMAP_NOTIFY
|
||||
&& event->xclient.format == 32) {
|
||||
WScreen *scr = wScreenForRootWindow(event->xclient.window);
|
||||
|
||||
if (!scr)
|
||||
return;
|
||||
|
||||
if (event->xclient.data.l[1] == 1) { /* starting */
|
||||
wColormapAllowClientInstallation(scr, True);
|
||||
} else { /* stopping */
|
||||
wColormapAllowClientInstallation(scr, False);
|
||||
}
|
||||
} else if (event->xclient.message_type == _XA_WINDOWMAKER_WM_FUNCTION) {
|
||||
WApplication *wapp;
|
||||
int done=0;
|
||||
@@ -1228,8 +1225,8 @@ handleColormapNotify(XEvent *event)
|
||||
&& ((wwin = wWindowFor(event->xcolormap.window)) || 1));
|
||||
|
||||
if (reinstall && scr->current_colormap!=None) {
|
||||
|
||||
XInstallColormap(dpy, scr->current_colormap);
|
||||
if (!scr->flags.colormap_stuff_blocked)
|
||||
XInstallColormap(dpy, scr->current_colormap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1286,6 +1283,9 @@ handleKeyPress(XEvent *event)
|
||||
int i;
|
||||
int modifiers;
|
||||
int command=-1;
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
XkbStateRec staterec;
|
||||
#endif /*KEEP_XKB_LOCK_STATUS*/
|
||||
|
||||
/* ignore CapsLock */
|
||||
modifiers = event->xkey.state & ValidModMask;
|
||||
@@ -1428,7 +1428,7 @@ handleKeyPress(XEvent *event)
|
||||
break;
|
||||
case WKBD_SELECT:
|
||||
if (ISMAPPED(wwin) && ISFOCUSED(wwin)) {
|
||||
wSelectWindow(wwin);
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
}
|
||||
break;
|
||||
case WKBD_FOCUSNEXT:
|
||||
@@ -1488,7 +1488,21 @@ handleKeyPress(XEvent *event)
|
||||
else if (scr->current_workspace==0 && wPreferences.ws_cycle)
|
||||
wWorkspaceChange(scr, scr->workspace_count-1);
|
||||
break;
|
||||
|
||||
case WKBD_WINDOW1:
|
||||
case WKBD_WINDOW2:
|
||||
case WKBD_WINDOW3:
|
||||
case WKBD_WINDOW4:
|
||||
if (scr->shortcutWindow[command-WKBD_WINDOW1]) {
|
||||
wMakeWindowVisible(scr->shortcutWindow[command-WKBD_WINDOW1]);
|
||||
} else if (wwin && ISMAPPED(wwin) && ISFOCUSED(wwin)) {
|
||||
scr->shortcutWindow[command-WKBD_WINDOW1] = wwin;
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
XFlush(dpy);
|
||||
wusleep(3000);
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
XFlush(dpy);
|
||||
}
|
||||
break;
|
||||
case WKBD_NEXTWSLAYER:
|
||||
case WKBD_PREVWSLAYER:
|
||||
{
|
||||
@@ -1518,6 +1532,17 @@ handleKeyPress(XEvent *event)
|
||||
if (!wPreferences.flags.noclip)
|
||||
wDockRaiseLower(scr->workspaces[scr->current_workspace]->clip);
|
||||
break;
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
case WKBD_TOGGLE:
|
||||
if(wPreferences.modelock){
|
||||
XkbGetState(dpy,XkbUseCoreKbd,&staterec);
|
||||
/*toggle*/
|
||||
XkbLockGroup(dpy,XkbUseCoreKbd,
|
||||
wwin->languagemode=staterec.compat_state&32?0:1);
|
||||
}
|
||||
break;
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/funcs.h
10
src/funcs.h
@@ -31,9 +31,6 @@ typedef void (WCallBack)(void *cdata);
|
||||
|
||||
typedef void (WDeathHandler)(pid_t pid, unsigned int status, void *cdata);
|
||||
|
||||
typedef void* WDeathHandlerID;
|
||||
|
||||
|
||||
void RestoreDesktop(WScreen *scr);
|
||||
|
||||
void Restart(char *manager);
|
||||
@@ -62,7 +59,7 @@ void UpdateSwitchMenu(WScreen *scr, WWindow *wwin, int action);
|
||||
|
||||
void UpdateSwitchMenuWorkspace(WScreen *scr, int workspace);
|
||||
|
||||
WDeathHandlerID wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata);
|
||||
WMagicNumber wAddDeathHandler(pid_t pid, WDeathHandler *callback, void *cdata);
|
||||
|
||||
void wColormapInstallForWindow(WScreen *scr, WWindow *wwin);
|
||||
|
||||
@@ -70,6 +67,7 @@ void wColormapInstallRoot(WScreen *scr);
|
||||
|
||||
void wColormapUninstallRoot(WScreen *scr);
|
||||
|
||||
void wColormapAllowClientInstallation(WScreen *scr, Bool starting);
|
||||
|
||||
Pixmap LoadIcon(WScreen *scr, char *path, char *mask, int title_height);
|
||||
|
||||
@@ -108,6 +106,10 @@ void ParseWindowName(proplist_t value, char **winstance, char **wclass,
|
||||
|
||||
char *GetShortcutString(char *text);
|
||||
|
||||
char *EscapeWM_CLASS(char *name, char *class);
|
||||
|
||||
void UnescapeWM_CLASS(char *str, char **name, char **class);
|
||||
|
||||
#ifdef NUMLOCK_HACK
|
||||
void wHackedGrabKey(int keycode, unsigned int modifiers,
|
||||
Window grab_window, Bool owner_events, int pointer_mode,
|
||||
|
||||
@@ -829,7 +829,7 @@ miniwindowMouseDown(WObjDescriptor *desc, XEvent *event)
|
||||
wRaiseFrame(icon->core);
|
||||
if (event->xbutton.state & ShiftMask) {
|
||||
wIconSelect(icon);
|
||||
wSelectWindow(icon->owner);
|
||||
wSelectWindow(icon->owner, !wwin->flags.selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,19 @@
|
||||
#define WKBD_NEXTWSLAYER 32
|
||||
#define WKBD_PREVWSLAYER 33
|
||||
|
||||
#define WKBD_LAST 34
|
||||
/* window shortcuts */
|
||||
#define WKBD_WINDOW1 34
|
||||
#define WKBD_WINDOW2 35
|
||||
#define WKBD_WINDOW3 36
|
||||
#define WKBD_WINDOW4 37
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
# define WKBD_TOGGLE 38
|
||||
# define WKBD_LAST 39
|
||||
#else
|
||||
# define WKBD_LAST 38
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
|
||||
|
||||
|
||||
typedef struct WShortKey {
|
||||
|
||||
@@ -94,6 +94,7 @@ Atom _XA_WM_DELETE_WINDOW;
|
||||
Atom _XA_WM_SAVE_YOURSELF;
|
||||
Atom _XA_WM_CLIENT_LEADER;
|
||||
Atom _XA_WM_COLORMAP_WINDOWS;
|
||||
Atom _XA_WM_COLORMAP_NOTIFY;
|
||||
|
||||
Atom _XA_GNUSTEP_WM_ATTR;
|
||||
Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
|
||||
|
||||
105
src/menu.c
105
src/menu.c
@@ -854,13 +854,13 @@ keyboardMenu(WMenu *menu)
|
||||
new_x = scr_width-MENUW(menu)-1;
|
||||
|
||||
move_menus(menu, new_x, new_y);
|
||||
|
||||
while (!done) {
|
||||
|
||||
while (!done && menu->flags.mapped) {
|
||||
XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
|
||||
WMMaskEvent(dpy, ExposureMask|ButtonMotionMask|ButtonPressMask
|
||||
|ButtonReleaseMask|KeyPressMask|KeyReleaseMask
|
||||
|SubstructureNotifyMask, &event);
|
||||
|
||||
|
||||
switch (event.type) {
|
||||
case KeyPress:
|
||||
ksym = XLookupKeysym(&event.xkey, 0);
|
||||
@@ -959,6 +959,7 @@ keyboardMenu(WMenu *menu)
|
||||
default:
|
||||
if (event.type==ButtonPress)
|
||||
done = 1;
|
||||
|
||||
WMHandleEvent(&event);
|
||||
}
|
||||
}
|
||||
@@ -1760,14 +1761,17 @@ delaySelection(void *data)
|
||||
{
|
||||
delay_data *d = (delay_data*)data;
|
||||
int x, y, entry_no;
|
||||
WMenu *menu;
|
||||
|
||||
d->magic = NULL;
|
||||
*(d->delayed_select) = 0;
|
||||
|
||||
if (findMenu(d->menu->menu->screen_ptr, &x, &y)) {
|
||||
entry_no = getEntryAt(d->menu, x, y);
|
||||
selectEntry(d->menu, entry_no);
|
||||
menu = findMenu(d->menu->menu->screen_ptr, &x, &y);
|
||||
if (menu && (d->menu == menu || d->delayed_select)) {
|
||||
entry_no = getEntryAt(menu, x, y);
|
||||
selectEntry(menu, entry_no);
|
||||
}
|
||||
if (d->delayed_select)
|
||||
*(d->delayed_select) = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1785,6 +1789,7 @@ menuMouseDown(WObjDescriptor *desc, XEvent *event)
|
||||
int delayed_select = 0;
|
||||
int entry_no;
|
||||
int x, y;
|
||||
int prevx, prevy;
|
||||
int old_frame_x = 0;
|
||||
int old_frame_y = 0;
|
||||
delay_data d_data = {NULL, NULL, NULL};
|
||||
@@ -1852,27 +1857,107 @@ menuMouseDown(WObjDescriptor *desc, XEvent *event)
|
||||
dragScrollMenuCallback(menu);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
prevx = bev->x_root;
|
||||
prevy = bev->y_root;
|
||||
while (!done) {
|
||||
int x, y;
|
||||
WMMaskEvent(dpy, ExposureMask|ButtonMotionMask|ButtonReleaseMask
|
||||
|ButtonPressMask, &ev);
|
||||
switch (ev.type) {
|
||||
case MotionNotify:
|
||||
case MotionNotify:
|
||||
smenu = findMenu(scr, &x, &y);
|
||||
|
||||
if (smenu == NULL) {
|
||||
/* moved mouse out of menu */
|
||||
|
||||
if (!delayed_select && d_data.magic) {
|
||||
WMDeleteTimerHandler(d_data.magic);
|
||||
d_data.magic = NULL;
|
||||
}
|
||||
if (menu==NULL
|
||||
|| (menu->selected_entry>=0
|
||||
&& menu->entries[menu->selected_entry]->cascade>=0))
|
||||
&& menu->entries[menu->selected_entry]->cascade>=0)) {
|
||||
prevx = ev.xmotion.x_root;
|
||||
prevy = ev.xmotion.y_root;
|
||||
|
||||
break;
|
||||
}
|
||||
selectEntry(menu, -1);
|
||||
menu = smenu;
|
||||
prevx = ev.xmotion.x_root;
|
||||
prevy = ev.xmotion.y_root;
|
||||
break;
|
||||
} else if (menu && menu!=smenu
|
||||
&& (menu->selected_entry<0
|
||||
|| menu->entries[menu->selected_entry]->cascade<0)) {
|
||||
selectEntry(menu, -1);
|
||||
|
||||
if (!delayed_select && d_data.magic) {
|
||||
WMDeleteTimerHandler(d_data.magic);
|
||||
d_data.magic = NULL;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* hysteresis for item selection */
|
||||
|
||||
/* check if the motion was to the side, indicating that
|
||||
* the user may want to cross to a submenu */
|
||||
if (!delayed_select && menu) {
|
||||
int dx;
|
||||
Bool moved_to_submenu;/* moved to direction of submenu */
|
||||
|
||||
dx = abs(prevx - ev.xmotion.x_root);
|
||||
|
||||
moved_to_submenu = False;
|
||||
if (dx > 0 /* if moved enough to the side */
|
||||
/* maybe a open submenu */
|
||||
&& menu->selected_entry>=0
|
||||
/* moving to the right direction */
|
||||
&& (wPreferences.align_menus
|
||||
|| ev.xmotion.y_root >= prevy)) {
|
||||
int index;
|
||||
|
||||
index = menu->entries[menu->selected_entry]->cascade;
|
||||
if (index>=0) {
|
||||
if (menu->cascades[index]->frame_x>menu->frame_x) {
|
||||
if (prevx < ev.xmotion.x_root)
|
||||
moved_to_submenu = True;
|
||||
} else {
|
||||
if (prevx > ev.xmotion.x_root)
|
||||
moved_to_submenu = True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (menu != smenu) {
|
||||
if (d_data.magic) {
|
||||
WMDeleteTimerHandler(d_data.magic);
|
||||
}
|
||||
d_data.magic = NULL;
|
||||
} else if (moved_to_submenu) {
|
||||
/* while we are moving, postpone the selection */
|
||||
if (d_data.magic) {
|
||||
WMDeleteTimerHandler(d_data.magic);
|
||||
}
|
||||
d_data.delayed_select = NULL;
|
||||
d_data.menu = menu;
|
||||
d_data.magic = WMAddTimerHandler(MENU_SELECT_DELAY,
|
||||
delaySelection,
|
||||
&d_data);
|
||||
prevx = ev.xmotion.x_root;
|
||||
prevy = ev.xmotion.y_root;
|
||||
break;
|
||||
} else {
|
||||
if (d_data.magic)
|
||||
WMDeleteTimerHandler(d_data.magic);
|
||||
d_data.magic = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevx = ev.xmotion.x_root;
|
||||
prevy = ev.xmotion.y_root;
|
||||
if (menu!=smenu) {
|
||||
/* pointer crossed menus */
|
||||
if (menu && menu->timer) {
|
||||
|
||||
140
src/misc.c
140
src/misc.c
@@ -1069,7 +1069,6 @@ void
|
||||
ParseWindowName(proplist_t value, char **winstance, char **wclass, char *where)
|
||||
{
|
||||
char *name;
|
||||
char *dot;
|
||||
|
||||
*winstance = *wclass = NULL;
|
||||
|
||||
@@ -1084,19 +1083,7 @@ ParseWindowName(proplist_t value, char **winstance, char **wclass, char *where)
|
||||
return;
|
||||
}
|
||||
|
||||
dot = strchr(name, '.');
|
||||
if (dot==name) {
|
||||
*wclass = wstrdup(&name[1]);
|
||||
*winstance = NULL;
|
||||
} else if (!dot) {
|
||||
*winstance = wstrdup(name);
|
||||
*wclass = NULL;
|
||||
} else {
|
||||
*dot = 0;
|
||||
*winstance = wstrdup(name);
|
||||
*dot = '.'; /* restore old string */
|
||||
*wclass = wstrdup(&dot[1]);
|
||||
}
|
||||
UnescapeWM_CLASS(name, winstance, wclass);
|
||||
}
|
||||
|
||||
|
||||
@@ -1190,3 +1177,128 @@ GetShortcutString(char *text)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
EscapeWM_CLASS(char *name, char *class)
|
||||
{
|
||||
char *ret;
|
||||
char *ename = NULL, *eclass = NULL;
|
||||
int i, j, l;
|
||||
|
||||
if (!name && !class)
|
||||
return NULL;
|
||||
|
||||
if (name) {
|
||||
l = strlen(name);
|
||||
ename = wmalloc(l*2);
|
||||
j = 0;
|
||||
for (i=0; i<l; i++) {
|
||||
if (name[i]=='\\') {
|
||||
ename[j++] = '\\';
|
||||
} else if (name[i]=='.') {
|
||||
ename[j++] = '\\';
|
||||
}
|
||||
ename[j++] = name[i];
|
||||
}
|
||||
ename[j] = 0;
|
||||
}
|
||||
if (class) {
|
||||
l = strlen(class);
|
||||
eclass = wmalloc(l*2);
|
||||
j = 0;
|
||||
for (i=0; i<l; i++) {
|
||||
if (class[i]=='\\') {
|
||||
eclass[j++] = '\\';
|
||||
} else if (class[i]=='.') {
|
||||
eclass[j++] = '\\';
|
||||
}
|
||||
eclass[j++] = class[i];
|
||||
}
|
||||
eclass[j] = 0;
|
||||
}
|
||||
|
||||
if (ename && eclass) {
|
||||
ret = wmalloc(strlen(ename)+strlen(eclass)+4);
|
||||
sprintf(ret, "%s.%s", ename, eclass);
|
||||
free(ename);
|
||||
free(eclass);
|
||||
} else if (ename) {
|
||||
ret = wstrdup(ename);
|
||||
free(ename);
|
||||
} else {
|
||||
ret = wstrdup(eclass);
|
||||
free(eclass);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
UnescapeWM_CLASS(char *str, char **name, char **class)
|
||||
{
|
||||
int i, j, k, dot;
|
||||
Bool esc;
|
||||
|
||||
j = strlen(str);
|
||||
*name = wmalloc(j);
|
||||
**name = 0;
|
||||
*class = wmalloc(j);
|
||||
**class = 0;
|
||||
|
||||
/* separate string in 2 parts */
|
||||
esc = False;
|
||||
dot = 0;
|
||||
for (i = 0; i < j; i++) {
|
||||
if (!esc) {
|
||||
if (str[i]=='\\') {
|
||||
esc = True;
|
||||
} else if (str[i]=='.') {
|
||||
dot = i;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
esc = False;
|
||||
}
|
||||
}
|
||||
|
||||
/* unescape strings */
|
||||
esc = False;
|
||||
k = 0;
|
||||
for (i = 0; i < dot; i++) {
|
||||
if (!esc) {
|
||||
if (str[i]=='\\') {
|
||||
esc = True;
|
||||
} else {
|
||||
(*name)[k++] = str[i];
|
||||
}
|
||||
} else {
|
||||
esc = False;
|
||||
}
|
||||
}
|
||||
(*name)[k] = 0;
|
||||
|
||||
esc = False;
|
||||
k = 0;
|
||||
for (i = dot+1; i<j; i++) {
|
||||
if (!esc) {
|
||||
if (str[i]=='\\') {
|
||||
esc = True;
|
||||
} else {
|
||||
(*class)[k++] = str[i];
|
||||
}
|
||||
} else {
|
||||
esc = False;
|
||||
}
|
||||
}
|
||||
(*class)[k] = 0;
|
||||
|
||||
if (!*name) {
|
||||
free(*name);
|
||||
*name = NULL;
|
||||
}
|
||||
if (!*class) {
|
||||
free(*class);
|
||||
*class = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,9 +59,6 @@ extern WPreferences wPreferences;
|
||||
|
||||
extern Atom _XA_WM_PROTOCOLS;
|
||||
|
||||
/** Locals **/
|
||||
static LinkedList *wSelectedWindows=NULL;
|
||||
|
||||
|
||||
|
||||
void
|
||||
@@ -572,8 +569,7 @@ static void
|
||||
flushMotion()
|
||||
{
|
||||
XEvent ev;
|
||||
|
||||
XSync(dpy, 0);
|
||||
|
||||
while (XCheckMaskEvent(dpy, ButtonMotionMask, &ev)) ;
|
||||
}
|
||||
|
||||
@@ -654,7 +650,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
|
||||
if (!wwin->flags.selected) {
|
||||
/* this window is not selected, unselect others and move only wwin */
|
||||
wUnselectWindows();
|
||||
wUnselectWindows(scr);
|
||||
}
|
||||
orig_x = ox = ev->xbutton.x_root;
|
||||
orig_y = oy = ev->xbutton.y_root;
|
||||
@@ -690,18 +686,18 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
}
|
||||
switch (event.type) {
|
||||
case KeyPress:
|
||||
if (wSelectedWindows)
|
||||
if (scr->selected_windows)
|
||||
break;
|
||||
if ((event.xkey.keycode == shiftl || event.xkey.keycode == shiftr)
|
||||
&& started) {
|
||||
if (!opaque_move)
|
||||
drawFrames(wwin, wSelectedWindows,
|
||||
drawFrames(wwin, scr->selected_windows,
|
||||
ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
|
||||
cyclePositionDisplay(wwin, x, y, w, h);
|
||||
|
||||
if (!opaque_move) {
|
||||
drawFrames(wwin, wSelectedWindows,
|
||||
drawFrames(wwin, scr->selected_windows,
|
||||
ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
}
|
||||
showPosition(wwin, x, y);
|
||||
@@ -713,12 +709,12 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
showPosition(wwin, x, y);
|
||||
|
||||
if (!opaque_move) {
|
||||
drawFrames(wwin, wSelectedWindows,
|
||||
drawFrames(wwin, scr->selected_windows,
|
||||
ox-orig_x, oy-orig_y, off_x, off_y);
|
||||
} else {
|
||||
doWindowMove(wwin, event.xmotion.x_root + XOffset,
|
||||
event.xmotion.y_root + YOffset,
|
||||
wSelectedWindows,
|
||||
scr->selected_windows,
|
||||
event.xmotion.x_root - ox,
|
||||
event.xmotion.y_root - oy,
|
||||
off_x, off_y);
|
||||
@@ -729,7 +725,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
|
||||
checkEdgeResistance(wwin, &x, &y, off_x, off_y);
|
||||
|
||||
if (!wSelectedWindows) {
|
||||
if (!scr->selected_windows) {
|
||||
if (wPreferences.move_display == WDIS_FRAME_CENTER)
|
||||
moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
|
||||
}
|
||||
@@ -806,7 +802,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
event.xmotion.x_root = orig_x;
|
||||
event.xmotion.y_root = orig_y;
|
||||
|
||||
if (!wSelectedWindows)
|
||||
if (!scr->selected_windows)
|
||||
mapPositionDisplay(wwin, x, y, w, h);
|
||||
|
||||
if (!opaque_move)
|
||||
@@ -816,7 +812,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
oy = event.xmotion.y_root;
|
||||
|
||||
if (started && !opaque_move)
|
||||
drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
drawFrames(wwin, scr->selected_windows, ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
|
||||
showPosition(wwin, x, y);
|
||||
break;
|
||||
@@ -830,12 +826,12 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
|
||||
if (started) {
|
||||
if (!opaque_move) {
|
||||
drawFrames(wwin, wSelectedWindows,
|
||||
drawFrames(wwin, scr->selected_windows,
|
||||
ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
XSync(dpy, 0);
|
||||
doWindowMove(wwin, event.xmotion.x_root + XOffset,
|
||||
event.xmotion.y_root + YOffset,
|
||||
wSelectedWindows,
|
||||
scr->selected_windows,
|
||||
ox - orig_x, oy - orig_y,
|
||||
off_x, off_y);
|
||||
}
|
||||
@@ -850,7 +846,7 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
wSetFocusTo(scr, wwin);
|
||||
}
|
||||
showPosition(wwin, x, y);
|
||||
if (!wSelectedWindows) {
|
||||
if (!scr->selected_windows) {
|
||||
/* get rid of the geometry window */
|
||||
unmapPositionDisplay(wwin);
|
||||
}
|
||||
@@ -862,12 +858,12 @@ wMouseMoveWindow(WWindow *wwin, XEvent *ev)
|
||||
|
||||
default:
|
||||
if (started && !opaque_move) {
|
||||
drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
drawFrames(wwin, scr->selected_windows, ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
XUngrabServer(dpy);
|
||||
WMHandleEvent(&event);
|
||||
XSync(dpy, False);
|
||||
XGrabServer(dpy);
|
||||
drawFrames(wwin, wSelectedWindows, ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
drawFrames(wwin, scr->selected_windows, ox - orig_x, oy - orig_y, off_x, off_y);
|
||||
} else {
|
||||
WMHandleEvent(&event);
|
||||
}
|
||||
@@ -969,7 +965,7 @@ wMouseResizeWindow(WWindow *wwin, XEvent *ev)
|
||||
puts("Resizing window");
|
||||
#endif
|
||||
|
||||
wUnselectWindows();
|
||||
wUnselectWindows(scr);
|
||||
rx1 = fx;
|
||||
rx2 = fx + fw - 1;
|
||||
ry1 = fy;
|
||||
@@ -1130,36 +1126,16 @@ wMouseResizeWindow(WWindow *wwin, XEvent *ev)
|
||||
#undef RESIZEBAR
|
||||
|
||||
void
|
||||
wUnselectWindows()
|
||||
wUnselectWindows(WScreen *scr)
|
||||
{
|
||||
WWindow *wwin;
|
||||
|
||||
while (wSelectedWindows) {
|
||||
wwin = wSelectedWindows->head;
|
||||
while (scr->selected_windows) {
|
||||
wwin = scr->selected_windows->head;
|
||||
if (wwin->flags.miniaturized && wwin->icon && wwin->icon->selected)
|
||||
wIconSelect(wwin->icon);
|
||||
|
||||
XSetWindowBorder(dpy, wwin->frame->core->window,
|
||||
wwin->screen_ptr->frame_border_pixel);
|
||||
wwin->flags.selected = 0;
|
||||
list_remove_head(&wSelectedWindows);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wSelectWindow(WWindow *wwin)
|
||||
{
|
||||
if (!wwin->flags.selected) {
|
||||
wwin->flags.selected = 1;
|
||||
XSetWindowBorder(dpy, wwin->frame->core->window,
|
||||
wwin->screen_ptr->white_pixel);
|
||||
wSelectedWindows = list_cons(wwin, wSelectedWindows);
|
||||
} else {
|
||||
wwin->flags.selected = 0;
|
||||
XSetWindowBorder(dpy, wwin->frame->core->window,
|
||||
wwin->screen_ptr->frame_border_pixel);
|
||||
wSelectedWindows = list_remove_elem(wSelectedWindows, wwin);
|
||||
wSelectWindow(wwin, False);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1178,10 +1154,7 @@ selectWindowsInside(WScreen *scr, int x1, int y1, int x2, int y2)
|
||||
&& (tmpw->frame_x >= x1) && (tmpw->frame_y >= y1)
|
||||
&& (tmpw->frame->core->width + tmpw->frame_x <= x2)
|
||||
&& (tmpw->frame->core->height + tmpw->frame_y <= y2)) {
|
||||
XSetWindowBorder(dpy, tmpw->frame->core->window,
|
||||
tmpw->screen_ptr->white_pixel);
|
||||
tmpw->flags.selected = 1;
|
||||
wSelectedWindows = list_cons(tmpw, wSelectedWindows);
|
||||
wSelectWindow(tmpw, True);
|
||||
}
|
||||
}
|
||||
tmpw = tmpw->prev;
|
||||
@@ -1211,7 +1184,7 @@ wSelectWindows(WScreen *scr, XEvent *ev)
|
||||
}
|
||||
XGrabServer(dpy);
|
||||
|
||||
wUnselectWindows();
|
||||
wUnselectWindows(scr);
|
||||
|
||||
XDrawRectangle(dpy, root, gc, xp, yp, w, h);
|
||||
while (1) {
|
||||
|
||||
@@ -409,16 +409,22 @@ smartPlaceWindow(WWindow *wwin, int *x_ret, int *y_ret,
|
||||
}
|
||||
|
||||
|
||||
/* Alfredo, shouldn't the cascade placement follow the !dock->lowered flag
|
||||
* like smart placement?
|
||||
* I didn't knew your intention about this, so I did not coded it, but it is
|
||||
* quite simple to do, if you think it should. -Dan
|
||||
*/
|
||||
static void
|
||||
cascadeWindow(WScreen *scr, WWindow *wwin, int *x_ret, int *y_ret,
|
||||
unsigned int width, unsigned int height, int h)
|
||||
{
|
||||
unsigned int extra_height;
|
||||
unsigned int scr_width;
|
||||
int xoffset = 0;
|
||||
|
||||
scr_width = scr->scr_width;
|
||||
if (scr->dock && !scr->dock->lowered) {
|
||||
if (scr->dock->on_right_side) {
|
||||
scr_width -= wPreferences.icon_size;
|
||||
} else {
|
||||
xoffset = wPreferences.icon_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (wwin->frame)
|
||||
extra_height = wwin->frame->top_width + wwin->frame->bottom_width;
|
||||
@@ -429,7 +435,7 @@ cascadeWindow(WScreen *scr, WWindow *wwin, int *x_ret, int *y_ret,
|
||||
*y_ret = h * scr->cascade_index + Y_ORIGIN;
|
||||
height += extra_height;
|
||||
|
||||
if (width + *x_ret > scr->scr_width || height + *y_ret > scr->scr_height) {
|
||||
if (width + *x_ret > scr_width || height + *y_ret > scr->scr_height) {
|
||||
scr->cascade_index = 0;
|
||||
*x_ret = h*scr->cascade_index + X_ORIGIN;
|
||||
*y_ret = h*scr->cascade_index + Y_ORIGIN;
|
||||
@@ -468,11 +474,11 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret,
|
||||
if (scr->dock && !scr->dock->lowered) {
|
||||
int x2;
|
||||
|
||||
x2 = *x_ret + wwin->client.width;
|
||||
x2 = *x_ret + width;
|
||||
if (scr->dock->on_right_side
|
||||
&& x2 > scr->scr_width - wPreferences.icon_size -
|
||||
DOCK_EXTRA_SPACE)
|
||||
*x_ret = scr->scr_width - wwin->client.width
|
||||
*x_ret = scr->scr_width - width
|
||||
- wPreferences.icon_size - DOCK_EXTRA_SPACE;
|
||||
else if (!scr->dock->on_right_side &&
|
||||
X_ORIGIN < wPreferences.icon_size + DOCK_EXTRA_SPACE)
|
||||
@@ -484,8 +490,8 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret,
|
||||
{
|
||||
int w, h;
|
||||
|
||||
w = (scr->scr_width-wwin->client.width);
|
||||
h = (scr->scr_height-wwin->client.height);
|
||||
w = (scr->scr_width - width);
|
||||
h = (scr->scr_height - height);
|
||||
if (w<1) w = 1;
|
||||
if (h<1) h = 1;
|
||||
*x_ret = rand()%w;
|
||||
@@ -493,11 +499,11 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret,
|
||||
if (scr->dock && !scr->dock->lowered) {
|
||||
int x2;
|
||||
|
||||
x2 = *x_ret + wwin->client.width;
|
||||
x2 = *x_ret + width;
|
||||
if (scr->dock->on_right_side
|
||||
&& x2 > scr->scr_width - wPreferences.icon_size -
|
||||
DOCK_EXTRA_SPACE)
|
||||
*x_ret = scr->scr_width - wwin->client.width
|
||||
*x_ret = scr->scr_width - width
|
||||
- wPreferences.icon_size - DOCK_EXTRA_SPACE;
|
||||
else if (!scr->dock->on_right_side
|
||||
&& *x_ret < wPreferences.icon_size)
|
||||
@@ -516,13 +522,13 @@ PlaceWindow(WWindow *wwin, int *x_ret, int *y_ret,
|
||||
|
||||
if (*x_ret < 0)
|
||||
*x_ret = 0;
|
||||
else if (*x_ret + wwin->client.width > scr->scr_width)
|
||||
*x_ret = scr->scr_width - wwin->client.width;
|
||||
else if (*x_ret + width > scr->scr_width)
|
||||
*x_ret = scr->scr_width - width;
|
||||
|
||||
if (*y_ret < 0)
|
||||
*y_ret = 0;
|
||||
else if (*y_ret + wwin->client.height > scr->scr_height)
|
||||
*y_ret = scr->scr_height - wwin->client.height;
|
||||
else if (*y_ret + height > scr->scr_height)
|
||||
*y_ret = scr->scr_height - height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ PropGetGNUstepWMAttr(Window window, GNUstepWMAttributes **attr)
|
||||
int fmt_ret;
|
||||
unsigned long nitems_ret;
|
||||
unsigned long bytes_after_ret;
|
||||
CARD32 *data;
|
||||
unsigned long *data;
|
||||
|
||||
if (XGetWindowProperty(dpy, window, _XA_GNUSTEP_WM_ATTR, 0, 9,
|
||||
False, _XA_GNUSTEP_WM_ATTR,
|
||||
@@ -161,7 +161,7 @@ PropGetMotifWMHints(Window window, MWMHints **mwmhints)
|
||||
int fmt_ret;
|
||||
unsigned long nitems_ret;
|
||||
unsigned long bytes_after_ret;
|
||||
CARD32 *data;
|
||||
unsigned long *data;
|
||||
|
||||
if (XGetWindowProperty(dpy, window, _XA_MOTIF_WM_HINTS, 0,
|
||||
PROP_MWM_HINTS_ELEMENTS,
|
||||
|
||||
20
src/screen.c
20
src/screen.c
@@ -66,6 +66,7 @@ extern Cursor wCursor[WCUR_LAST];
|
||||
extern WPreferences wPreferences;
|
||||
extern Atom _XA_WINDOWMAKER_STATE;
|
||||
|
||||
|
||||
extern int wScreenCount;
|
||||
|
||||
extern WDDomain *WDWindowMaker;
|
||||
@@ -282,14 +283,23 @@ allocGCs(WScreen *scr)
|
||||
|
||||
/* frame GC */
|
||||
wGetColor(scr, DEF_FRAME_COLOR, &color);
|
||||
|
||||
gcv.foreground = color.pixel;
|
||||
gcv.function = GXxor;
|
||||
/* this will raise the probability of the XORed color being different
|
||||
* of the original color in PseudoColor when not all color cells are
|
||||
* initialized */
|
||||
if (DefaultVisual(dpy, scr->screen)->class==PseudoColor)
|
||||
gcv.plane_mask = (1<<(scr->depth-1))|1;
|
||||
else
|
||||
gcv.plane_mask = AllPlanes;
|
||||
gcv.foreground = color.pixel;
|
||||
if (gcv.foreground == 0)
|
||||
gcv.foreground = 1;
|
||||
gcv.line_width = DEF_FRAME_THICKNESS;
|
||||
gcv.subwindow_mode = IncludeInferiors;
|
||||
gcv.graphics_exposures = False;
|
||||
scr->frame_gc = XCreateGC(dpy, scr->root_win, GCForeground|GCGraphicsExposures
|
||||
|GCFunction|GCSubwindowMode|GCLineWidth, &gcv);
|
||||
|GCFunction|GCSubwindowMode|GCLineWidth
|
||||
|GCPlaneMask, &gcv);
|
||||
|
||||
/* line GC */
|
||||
gcv.foreground = color.pixel;
|
||||
@@ -536,7 +546,7 @@ wScreenInit(int screen_number)
|
||||
long event_mask;
|
||||
WMColor *color;
|
||||
XErrorHandler oldHandler;
|
||||
|
||||
|
||||
scr = wmalloc(sizeof(WScreen));
|
||||
memset(scr, 0, sizeof(WScreen));
|
||||
|
||||
@@ -553,7 +563,7 @@ wScreenInit(int screen_number)
|
||||
oldHandler = XSetErrorHandler((XErrorHandler)alreadyRunningError);
|
||||
|
||||
event_mask = EVENT_MASK;
|
||||
|
||||
|
||||
if (wPreferences.disable_root_mouse)
|
||||
event_mask &= ~(ButtonPressMask|ButtonReleaseMask);
|
||||
XSelectInput(dpy, scr->root_win, event_mask);
|
||||
|
||||
@@ -95,6 +95,8 @@ typedef struct _WScreen {
|
||||
* Use this list if you want to
|
||||
* traverse the entire window list
|
||||
*/
|
||||
|
||||
struct LinkedList *selected_windows;
|
||||
|
||||
struct WAppIcon *app_icon_list; /* list of all app-icons on screen */
|
||||
|
||||
@@ -242,11 +244,14 @@ typedef struct _WScreen {
|
||||
WMHandlerID *autoRaiseTimer;
|
||||
Window autoRaiseWindow; /* window that is scheduled to be
|
||||
* raised */
|
||||
|
||||
/* for window shortcuts */
|
||||
struct WWindow *shortcutWindow[4];
|
||||
|
||||
#ifdef XDE_DND
|
||||
char *xdestring;
|
||||
#endif
|
||||
|
||||
|
||||
struct {
|
||||
unsigned int startup:1; /* during window manager startup */
|
||||
unsigned int regenerate_icon_textures:1;
|
||||
@@ -257,6 +262,8 @@ typedef struct _WScreen {
|
||||
unsigned int supports_tiff:1;
|
||||
unsigned int clip_balloon_mapped:1;
|
||||
unsigned int next_click_is_not_double:1;
|
||||
/* some client has issued a WM_COLORMAP_NOTIFY */
|
||||
unsigned int colormap_stuff_blocked:1;
|
||||
} flags;
|
||||
} WScreen;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Window Maker window manager
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1997, 1998 Alfredo K. Kojima
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@@ -102,6 +102,7 @@ extern Atom _XA_WM_DELETE_WINDOW;
|
||||
extern Atom _XA_WM_SAVE_YOURSELF;
|
||||
extern Atom _XA_WM_CLIENT_LEADER;
|
||||
extern Atom _XA_WM_COLORMAP_WINDOWS;
|
||||
extern Atom _XA_WM_COLORMAP_NOTIFY;
|
||||
|
||||
extern Atom _XA_GNUSTEP_WM_ATTR;
|
||||
|
||||
@@ -588,6 +589,9 @@ StartUp(Bool defaultScreenOnly)
|
||||
wWinContext = XUniqueContext();
|
||||
wAppWinContext = XUniqueContext();
|
||||
wStackContext = XUniqueContext();
|
||||
|
||||
/* _XA_VERSION = XInternAtom(dpy, "VERSION", False);*/
|
||||
|
||||
_XA_WM_STATE = XInternAtom(dpy, "WM_STATE", False);
|
||||
_XA_WM_CHANGE_STATE = XInternAtom(dpy, "WM_CHANGE_STATE", False);
|
||||
_XA_WM_PROTOCOLS = XInternAtom(dpy, "WM_PROTOCOLS", False);
|
||||
@@ -596,7 +600,8 @@ StartUp(Bool defaultScreenOnly)
|
||||
_XA_WM_SAVE_YOURSELF = XInternAtom(dpy, "WM_SAVE_YOURSELF", False);
|
||||
_XA_WM_CLIENT_LEADER = XInternAtom(dpy, "WM_CLIENT_LEADER", False);
|
||||
_XA_WM_COLORMAP_WINDOWS = XInternAtom(dpy, "WM_COLORMAP_WINDOWS", False);
|
||||
|
||||
_XA_WM_COLORMAP_NOTIFY = XInternAtom(dpy, "WM_COLORMAP_NOTIFY", False);
|
||||
|
||||
_XA_GNUSTEP_WM_ATTR = XInternAtom(dpy, GNUSTEP_WM_ATTR_NAME, False);
|
||||
#ifdef MWM_HINTS
|
||||
_XA_MOTIF_WM_HINTS = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
|
||||
|
||||
@@ -64,20 +64,8 @@ focusWindow(WMenu *menu, WMenuEntry *entry)
|
||||
|
||||
wwin = (WWindow*)entry->clientdata;
|
||||
scr = wwin->screen_ptr;
|
||||
|
||||
wWorkspaceChange(menu->frame->screen_ptr, wwin->frame->workspace);
|
||||
|
||||
if (wwin->flags.shaded) {
|
||||
wUnshadeWindow(wwin);
|
||||
}
|
||||
if (wwin->flags.hidden) {
|
||||
wUnhideApplication(wApplicationOf(wwin->main_window), False, False);
|
||||
} else if (wwin->flags.miniaturized) {
|
||||
wDeiconifyWindow(wwin);
|
||||
} else {
|
||||
wSetFocusTo(menu->frame->screen_ptr, wwin);
|
||||
wRaiseFrame(wwin->frame->core);
|
||||
}
|
||||
wMakeWindowVisible(wwin);
|
||||
|
||||
x = wwin->frame_x;
|
||||
y = wwin->frame_y;
|
||||
|
||||
@@ -277,9 +277,12 @@
|
||||
|
||||
#define HIDE_ANIMATION_STEPS (MINIATURIZE_ANIMATION_STEPS*2/3)
|
||||
|
||||
|
||||
/* delay before balloon is showed */
|
||||
#define BALLOON_DELAY 1000
|
||||
|
||||
/* delay for menu item selection hysteresis */
|
||||
#define MENU_SELECT_DELAY 300
|
||||
|
||||
/* animation speed constants */
|
||||
|
||||
/* icon slide */
|
||||
@@ -466,6 +469,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XKB_MODELOCK
|
||||
#define KEEP_XKB_LOCK_STATUS
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBINTL_H && I18N
|
||||
# include <libintl.h>
|
||||
# define _(text) gettext(text)
|
||||
|
||||
@@ -277,9 +277,12 @@
|
||||
|
||||
#define HIDE_ANIMATION_STEPS (MINIATURIZE_ANIMATION_STEPS*2/3)
|
||||
|
||||
|
||||
/* delay before balloon is showed */
|
||||
#define BALLOON_DELAY 1000
|
||||
|
||||
/* delay for menu item selection hysteresis */
|
||||
#define MENU_SELECT_DELAY 300
|
||||
|
||||
/* animation speed constants */
|
||||
|
||||
/* icon slide */
|
||||
@@ -466,6 +469,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XKB_MODELOCK
|
||||
#define KEEP_XKB_LOCK_STATUS
|
||||
#endif
|
||||
|
||||
#if HAVE_LIBINTL_H && I18N
|
||||
# include <libintl.h>
|
||||
# define _(text) gettext(text)
|
||||
|
||||
71
src/window.c
71
src/window.c
@@ -27,10 +27,14 @@
|
||||
#ifdef SHAPE
|
||||
#include <X11/extensions/shape.h>
|
||||
#endif
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
# include <X11/XKBlib.h>
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "WindowMaker.h"
|
||||
#include "GNUstep.h"
|
||||
#ifdef MWM_HINTS
|
||||
@@ -146,7 +150,7 @@ wWindowFor(Window window)
|
||||
}
|
||||
|
||||
|
||||
WWindow *
|
||||
WWindow*
|
||||
wWindowCreate()
|
||||
{
|
||||
WWindow *wwin;
|
||||
@@ -167,8 +171,16 @@ wWindowCreate()
|
||||
void
|
||||
wWindowDestroy(WWindow *wwin)
|
||||
{
|
||||
int i;
|
||||
|
||||
wwin->flags.destroyed = 1;
|
||||
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (wwin->screen_ptr->shortcutWindow[i] == wwin) {
|
||||
wwin->screen_ptr->shortcutWindow[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (wwin->normal_hints)
|
||||
free(wwin->normal_hints);
|
||||
|
||||
@@ -835,6 +847,7 @@ wManageWindow(WScreen *scr, Window window)
|
||||
XReparentWindow(dpy, wwin->client_win, wwin->frame->core->window,
|
||||
0, wwin->frame->top_width);
|
||||
|
||||
#if 0
|
||||
{
|
||||
int gx, gy;
|
||||
|
||||
@@ -846,7 +859,7 @@ wManageWindow(WScreen *scr, Window window)
|
||||
if (gy > 0)
|
||||
y -= wwin->frame->top_width + wwin->frame->bottom_width;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* wWindowConfigure() will init the client window's size
|
||||
* (wwin->client.{width,height}) and all other geometry
|
||||
@@ -1046,6 +1059,7 @@ wManageInternalWindow(WScreen *scr, Window window, Window owner,
|
||||
wwin->window_flags.omnipresent = 1;
|
||||
wwin->window_flags.no_shadeable = 1;
|
||||
wwin->window_flags.no_resizable = 1;
|
||||
wwin->window_flags.no_miniaturizable = 1;
|
||||
|
||||
wwin->focus_mode = WFM_PASSIVE;
|
||||
|
||||
@@ -1186,12 +1200,19 @@ wUnmanageWindow(WWindow *wwin, int restore)
|
||||
WWindow *pwin = wwin->inspector->frame; /* the inspector window */
|
||||
(*pwin->frame->on_click_right)(NULL, pwin, NULL);
|
||||
}
|
||||
|
||||
/* Close window menu if it's open for this window */
|
||||
if (wwin->flags.menu_open_for_me) {
|
||||
CloseWindowMenu(scr);
|
||||
}
|
||||
if (!wwin->flags.internal_window)
|
||||
XRemoveFromSaveSet(dpy, wwin->client_win);
|
||||
XSelectInput(dpy, wwin->client_win, NoEventMask);
|
||||
|
||||
XUnmapWindow(dpy, frame->window);
|
||||
|
||||
/* deselect window */
|
||||
if (wwin->flags.selected)
|
||||
wSelectWindow(wwin);
|
||||
wSelectWindow(wwin, False);
|
||||
|
||||
/* remove all pending events on window */
|
||||
/* I think this only matters for autoraise */
|
||||
@@ -1289,7 +1310,15 @@ wUnmanageWindow(WWindow *wwin, int restore)
|
||||
|
||||
void
|
||||
wWindowFocus(WWindow *wwin)
|
||||
{
|
||||
{
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
if (wPreferences.modelock) {
|
||||
if (!wwin->flags.focused) {
|
||||
XkbLockGroup(dpy, XkbUseCoreKbd, wwin->languagemode);
|
||||
}
|
||||
}
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
|
||||
wFrameWindowChangeState(wwin->frame, WS_FOCUSED);
|
||||
|
||||
wwin->flags.focused=1;
|
||||
@@ -1312,6 +1341,17 @@ wWindowMap(WWindow *wwin)
|
||||
void
|
||||
wWindowUnfocus(WWindow *wwin)
|
||||
{
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
static XkbStateRec staterec;
|
||||
if (wPreferences.modelock) {
|
||||
if (wwin->flags.focused) {
|
||||
XkbGetState(dpy,XkbUseCoreKbd,&staterec);
|
||||
wwin->languagemode=staterec.compat_state&32?1:0;
|
||||
XkbLockGroup(dpy,XkbUseCoreKbd,0); /* reset to workspace */
|
||||
}
|
||||
}
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
|
||||
CloseWindowMenu(wwin->screen_ptr);
|
||||
|
||||
wFrameWindowChangeState(wwin->frame, wwin->flags.semi_focused
|
||||
@@ -2275,7 +2315,7 @@ titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event)
|
||||
if (event->xbutton.state & ShiftMask) {
|
||||
dir |= MAX_HORIZONTAL;
|
||||
if (!(event->xbutton.state & ControlMask))
|
||||
wSelectWindow(wwin);
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
}
|
||||
|
||||
/* maximize window */
|
||||
@@ -2291,8 +2331,8 @@ titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event)
|
||||
wHideOtherApplications(wwin);
|
||||
}
|
||||
} else if (event->xbutton.button==Button2) {
|
||||
wSelectWindow(wwin);
|
||||
}
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2368,20 +2408,9 @@ titlebarMouseDown(WCoreWindow *sender, void *data, XEvent *event)
|
||||
}
|
||||
if ((event->xbutton.state & ShiftMask)
|
||||
&& !(event->xbutton.state & ControlMask)) {
|
||||
wSelectWindow(wwin);
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
if (XGrabPointer(dpy, wwin->frame->titlebar->window, False,
|
||||
ButtonMotionMask|ButtonReleaseMask|ButtonPressMask,
|
||||
GrabModeAsync, GrabModeAsync, None,
|
||||
None, CurrentTime)!=GrabSuccess) {
|
||||
#ifdef DEBUG0
|
||||
wwarning("pointer grab failed for window move");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* move the window */
|
||||
wMouseMoveWindow(wwin, event);
|
||||
XUngrabPointer(dpy, CurrentTime);
|
||||
|
||||
@@ -187,6 +187,10 @@ typedef struct WWindow {
|
||||
|
||||
FocusMode focus_mode; /* type of keyboard input focus */
|
||||
|
||||
#ifdef KEEP_XKB_LOCK_STATUS
|
||||
int languagemode;
|
||||
#endif /* KEEP_XKB_LOCK_STATUS */
|
||||
|
||||
#ifdef MONITOR_HEARTBEAT
|
||||
time_t last_beat;
|
||||
#endif
|
||||
@@ -223,6 +227,8 @@ typedef struct WWindow {
|
||||
unsigned int inspector_open:1; /* attrib inspector is already open */
|
||||
|
||||
unsigned int destroyed:1; /* window was already destroyed */
|
||||
|
||||
unsigned int menu_open_for_me:1; /* window commands menu */
|
||||
} flags; /* state of the window */
|
||||
|
||||
struct WIcon *icon; /* icon info for the window */
|
||||
|
||||
137
src/winmenu.c
137
src/winmenu.c
@@ -47,10 +47,10 @@
|
||||
#define MC_MINIATURIZE 1
|
||||
#define MC_SHADE 2
|
||||
#define MC_HIDE 3
|
||||
#define MC_HIDE_OTHERS 4
|
||||
#define MC_SELECT 5
|
||||
#define MC_DUMMY_MOVETO 6
|
||||
#define MC_PROPERTIES 7
|
||||
#define MC_SELECT 4
|
||||
#define MC_DUMMY_MOVETO 5
|
||||
#define MC_PROPERTIES 6
|
||||
#define MC_SHORTCUT 7
|
||||
|
||||
#define MC_CLOSE 8
|
||||
#define MC_KILL 9
|
||||
@@ -111,7 +111,7 @@ execMenuCommand(WMenu *menu, WMenuEntry *entry)
|
||||
wShadeWindow(wwin);
|
||||
break;
|
||||
case MC_SELECT:
|
||||
wSelectWindow(wwin);
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
break;
|
||||
case MC_PROPERTIES:
|
||||
if (wwin->wm_class || wwin->wm_instance)
|
||||
@@ -122,9 +122,6 @@ execMenuCommand(WMenu *menu, WMenuEntry *entry)
|
||||
wapp = wApplicationOf(wwin->main_window);
|
||||
wHideApplication(wapp);
|
||||
break;
|
||||
case MC_HIDE_OTHERS:
|
||||
wHideOtherApplications(wwin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,12 +131,26 @@ switchWSCommand(WMenu *menu, WMenuEntry *entry)
|
||||
{
|
||||
WWindow *wwin = (WWindow*)entry->clientdata;
|
||||
|
||||
if (wwin->flags.selected)
|
||||
wSelectWindow(wwin);
|
||||
wSelectWindow(wwin, False);
|
||||
wWindowChangeWorkspace(wwin, entry->order);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
makeShortcutCommand(WMenu *menu, WMenuEntry *entry)
|
||||
{
|
||||
WWindow *wwin = (WWindow*)entry->clientdata;
|
||||
|
||||
wwin->screen_ptr->shortcutWindow[entry->order] = wwin;
|
||||
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
XFlush(dpy);
|
||||
wusleep(3000);
|
||||
wSelectWindow(wwin, !wwin->flags.selected);
|
||||
XFlush(dpy);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
updateWorkspaceMenu(WMenu *menu)
|
||||
{
|
||||
@@ -172,20 +183,94 @@ updateWorkspaceMenu(WMenu *menu)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
updateMakeShortcutMenu(WMenu *menu, WWindow *wwin)
|
||||
{
|
||||
WMenu *smenu = menu->cascades[menu->entries[MC_SHORTCUT]->cascade];
|
||||
int i;
|
||||
char *buffer;
|
||||
KeyCode kcode;
|
||||
|
||||
if (!smenu)
|
||||
return;
|
||||
|
||||
buffer = wmalloc(strlen(_("Shortcut"))+16);
|
||||
|
||||
for (i=0; i<smenu->entry_no; i++) {
|
||||
char *tmp;
|
||||
WWindow *twin = wwin->screen_ptr->shortcutWindow[i];
|
||||
WMenuEntry *entry = smenu->entries[i];
|
||||
|
||||
sprintf(buffer, "%s %s %i", twin ? (twin == wwin ? "+" : "-" ) : " ",
|
||||
_("Shortcut"), i+1);
|
||||
|
||||
if (strcmp(buffer, entry->text)!=0) {
|
||||
free(entry->text);
|
||||
entry->text = wstrdup(buffer);
|
||||
smenu->flags.realized = 0;
|
||||
}
|
||||
|
||||
kcode = wKeyBindings[WKBD_WINDOW1+i].keycode;
|
||||
|
||||
if (kcode) {
|
||||
if ((tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0)))
|
||||
&& (!entry->rtext || strcmp(tmp, entry->rtext)!=0)) {
|
||||
if (entry->rtext)
|
||||
free(entry->rtext);
|
||||
entry->rtext = wstrdup(tmp);
|
||||
smenu->flags.realized = 0;
|
||||
}
|
||||
wMenuSetEnabled(smenu, i, True);
|
||||
} else {
|
||||
wMenuSetEnabled(smenu, i, False);
|
||||
if (entry->rtext) {
|
||||
free(entry->rtext);
|
||||
entry->rtext = NULL;
|
||||
smenu->flags.realized = 0;
|
||||
}
|
||||
}
|
||||
entry->clientdata = wwin;
|
||||
}
|
||||
free(buffer);
|
||||
if (!smenu->flags.realized)
|
||||
wMenuRealize(smenu);
|
||||
}
|
||||
|
||||
|
||||
static WMenu*
|
||||
makeWorkspaceMenu(WScreen *scr)
|
||||
{
|
||||
WMenu *menu;
|
||||
|
||||
menu = wMenuCreate(scr, NULL, False);
|
||||
if (!menu)
|
||||
wwarning(_("could not create workspace submenu for window menu"));
|
||||
if (!menu) {
|
||||
wwarning(_("could not create submenu for window menu"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
updateWorkspaceMenu(menu);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static WMenu*
|
||||
makeMakeShortcutMenu(WScreen *scr)
|
||||
{
|
||||
WMenu *menu;
|
||||
|
||||
menu = wMenuCreate(scr, NULL, False);
|
||||
if (!menu) {
|
||||
wwarning(_("could not create submenu for window menu"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wMenuAddCallback(menu, "", makeShortcutCommand, NULL);
|
||||
wMenuAddCallback(menu, "", makeShortcutCommand, NULL);
|
||||
wMenuAddCallback(menu, "", makeShortcutCommand, NULL);
|
||||
wMenuAddCallback(menu, "", makeShortcutCommand, NULL);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static WMenu*
|
||||
createWindowMenu(WScreen *scr)
|
||||
@@ -233,23 +318,25 @@ createWindowMenu(WScreen *scr)
|
||||
if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
|
||||
entry->rtext = wstrdup(tmp);
|
||||
}
|
||||
entry = wMenuAddCallback(menu, _("Hide Others"), execMenuCommand, NULL);
|
||||
|
||||
entry = wMenuAddCallback(menu, _("Select"), execMenuCommand, NULL);
|
||||
if (wKeyBindings[WKBD_SELECT].keycode!=0) {
|
||||
kcode = wKeyBindings[WKBD_SELECT].keycode;
|
||||
|
||||
|
||||
if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
|
||||
entry->rtext = wstrdup(tmp);
|
||||
}
|
||||
|
||||
|
||||
entry = wMenuAddCallback(menu, _("Move To"), NULL, NULL);
|
||||
scr->workspace_submenu = makeWorkspaceMenu(scr);
|
||||
if (scr->workspace_submenu)
|
||||
wMenuEntrySetCascade(menu, entry, scr->workspace_submenu);
|
||||
|
||||
entry = wMenuAddCallback(menu, _("Attributes..."), execMenuCommand, NULL);
|
||||
|
||||
|
||||
entry = wMenuAddCallback(menu, _("Select Shortcut"), NULL, NULL);
|
||||
wMenuEntrySetCascade(menu, entry, makeMakeShortcutMenu(scr));
|
||||
|
||||
entry = wMenuAddCallback(menu, _("Close"), execMenuCommand, NULL);
|
||||
if (wKeyBindings[WKBD_CLOSE].keycode!=0) {
|
||||
kcode = wKeyBindings[WKBD_CLOSE].keycode;
|
||||
@@ -266,9 +353,17 @@ createWindowMenu(WScreen *scr)
|
||||
void
|
||||
CloseWindowMenu(WScreen *scr)
|
||||
{
|
||||
if (scr->window_menu && scr->window_menu->flags.mapped)
|
||||
wMenuUnmap(scr->window_menu);
|
||||
if (scr->window_menu) {
|
||||
if (scr->window_menu->flags.mapped)
|
||||
wMenuUnmap(scr->window_menu);
|
||||
|
||||
if (scr->window_menu->entries[0]->clientdata) {
|
||||
WWindow *wwin = (WWindow*)scr->window_menu->entries[0]->clientdata;
|
||||
|
||||
wwin->flags.menu_open_for_me = 0;
|
||||
}
|
||||
scr->window_menu->entries[0]->clientdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -280,11 +375,14 @@ OpenWindowMenu(WWindow *wwin, int x, int y, int keyboard)
|
||||
WScreen *scr = wwin->screen_ptr;
|
||||
int i;
|
||||
|
||||
wwin->flags.menu_open_for_me = 1;
|
||||
|
||||
if (!scr->window_menu) {
|
||||
scr->window_menu = createWindowMenu(scr);
|
||||
} else {
|
||||
updateWorkspaceMenu(scr->workspace_submenu);
|
||||
}
|
||||
|
||||
menu = scr->window_menu;
|
||||
if (menu->flags.mapped) {
|
||||
wMenuUnmap(menu);
|
||||
@@ -292,6 +390,8 @@ OpenWindowMenu(WWindow *wwin, int x, int y, int keyboard)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
updateMakeShortcutMenu(menu, wwin);
|
||||
|
||||
wMenuSetEnabled(menu, MC_HIDE, wapp!=NULL
|
||||
&& !wapp->main_window_desc->window_flags.no_appicon);
|
||||
@@ -316,6 +416,7 @@ OpenWindowMenu(WWindow *wwin, int x, int y, int keyboard)
|
||||
for (i = 0; i < menu->entry_no; i++) {
|
||||
menu->entries[i]->clientdata = wwin;
|
||||
}
|
||||
|
||||
for (i = 0; i < scr->workspace_submenu->entry_no; i++) {
|
||||
scr->workspace_submenu->entries[i]->clientdata = wwin;
|
||||
if (i == scr->current_workspace) {
|
||||
|
||||
Reference in New Issue
Block a user