mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 20:38:08 +01:00
Partial fix for focus stealing
By turning M'bert's d6c134 around a bit and adapting the surroundings,
allow _NET_ACTIVE_WINDOW only if fulfilling it doesn't cause annoying
unwanted changes in the workspace. This is now the default behaviour;
unconditional focus stealing can be enabled on a per-client basis in the
Advanced Options window menu ("Focus across workspaces").
This commit is contained in:
committed by
Carlos R. Mafra
parent
5fa8b979b9
commit
f6fefbd9b6
@@ -74,7 +74,7 @@ static WMPropList *AStartMaximized;
|
|||||||
static WMPropList *AStartHidden; /* app */
|
static WMPropList *AStartHidden; /* app */
|
||||||
static WMPropList *ADontSaveSession; /* app */
|
static WMPropList *ADontSaveSession; /* app */
|
||||||
static WMPropList *AEmulateAppIcon;
|
static WMPropList *AEmulateAppIcon;
|
||||||
static WMPropList *ADontFocusAcrossWorkspace;
|
static WMPropList *AFocusAcrossWorkspace;
|
||||||
static WMPropList *AFullMaximize;
|
static WMPropList *AFullMaximize;
|
||||||
static WMPropList *ASharedAppIcon; /* app */
|
static WMPropList *ASharedAppIcon; /* app */
|
||||||
#ifdef XKB_BUTTON_HINT
|
#ifdef XKB_BUTTON_HINT
|
||||||
@@ -111,7 +111,7 @@ static void init_wdefaults(WScreen * scr)
|
|||||||
AStartMaximized = WMCreatePLString("StartMaximized");
|
AStartMaximized = WMCreatePLString("StartMaximized");
|
||||||
ADontSaveSession = WMCreatePLString("DontSaveSession");
|
ADontSaveSession = WMCreatePLString("DontSaveSession");
|
||||||
AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
|
AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
|
||||||
ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace");
|
AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
|
||||||
AFullMaximize = WMCreatePLString("FullMaximize");
|
AFullMaximize = WMCreatePLString("FullMaximize");
|
||||||
ASharedAppIcon = WMCreatePLString("SharedAppIcon");
|
ASharedAppIcon = WMCreatePLString("SharedAppIcon");
|
||||||
#ifdef XKB_BUTTON_HINT
|
#ifdef XKB_BUTTON_HINT
|
||||||
@@ -303,8 +303,8 @@ wDefaultFillAttributes(WScreen * scr, char *instance, char *class,
|
|||||||
value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
|
value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
|
||||||
APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
|
APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
|
||||||
|
|
||||||
value = get_value(dw, dc, dn, da, ADontFocusAcrossWorkspace, No, useGlobalDefault);
|
value = get_value(dw, dc, dn, da, AFocusAcrossWorkspace, No, useGlobalDefault);
|
||||||
APPLY_VAL(value, dont_focus_across_wksp, ADontFocusAcrossWorkspace);
|
APPLY_VAL(value, focus_across_wksp, AFocusAcrossWorkspace);
|
||||||
|
|
||||||
value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
|
value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
|
||||||
APPLY_VAL(value, full_maximize, AFullMaximize);
|
APPLY_VAL(value, full_maximize, AFullMaximize);
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ typedef struct {
|
|||||||
unsigned int dont_move_off:1;
|
unsigned int dont_move_off:1;
|
||||||
|
|
||||||
unsigned int no_focusable:1;
|
unsigned int no_focusable:1;
|
||||||
unsigned int dont_focus_across_wksp:1; /* don't let wmaker switch workspace to follow
|
unsigned int focus_across_wksp:1; /* let wmaker switch workspace to follow
|
||||||
* a focus request */
|
* a focus request */
|
||||||
|
|
||||||
unsigned int always_user_icon:1; /* ignore client IconPixmap or
|
unsigned int always_user_icon:1; /* ignore client IconPixmap or
|
||||||
* IconWindow */
|
* IconWindow */
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ static WMPropList *ASkipWindowList;
|
|||||||
static WMPropList *ASkipSwitchPanel;
|
static WMPropList *ASkipSwitchPanel;
|
||||||
static WMPropList *AKeepInsideScreen;
|
static WMPropList *AKeepInsideScreen;
|
||||||
static WMPropList *AUnfocusable;
|
static WMPropList *AUnfocusable;
|
||||||
static WMPropList *ADontFocusAcrossWorkspace;
|
static WMPropList *AFocusAcrossWorkspace;
|
||||||
static WMPropList *AAlwaysUserIcon;
|
static WMPropList *AAlwaysUserIcon;
|
||||||
static WMPropList *AStartMiniaturized;
|
static WMPropList *AStartMiniaturized;
|
||||||
static WMPropList *AStartMaximized;
|
static WMPropList *AStartMaximized;
|
||||||
@@ -190,7 +190,7 @@ static void make_keys(void)
|
|||||||
ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
|
ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
|
||||||
AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
|
AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
|
||||||
AUnfocusable = WMCreatePLString("Unfocusable");
|
AUnfocusable = WMCreatePLString("Unfocusable");
|
||||||
ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace");
|
AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
|
||||||
AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
|
AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
|
||||||
AStartMiniaturized = WMCreatePLString("StartMiniaturized");
|
AStartMiniaturized = WMCreatePLString("StartMiniaturized");
|
||||||
AStartMaximized = WMCreatePLString("StartMaximized");
|
AStartMaximized = WMCreatePLString("StartMaximized");
|
||||||
@@ -595,7 +595,7 @@ static void saveSettings(WMButton * button, InspectorPanel * panel)
|
|||||||
different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
|
different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags);
|
||||||
|
|
||||||
value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
|
value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No;
|
||||||
different |= insertAttribute(dict, winDic, ADontFocusAcrossWorkspace, value, flags);
|
different |= insertAttribute(dict, winDic, AFocusAcrossWorkspace, value, flags);
|
||||||
|
|
||||||
#ifdef XKB_BUTTON_HINT
|
#ifdef XKB_BUTTON_HINT
|
||||||
value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
|
value = (WMGetButtonSelected(panel->moreChk[10]) != 0) ? Yes : No;
|
||||||
@@ -773,7 +773,7 @@ static void applySettings(WMButton * button, InspectorPanel * panel)
|
|||||||
WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
|
WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[6]));
|
||||||
WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
|
WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[7]));
|
||||||
WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
|
WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[8]));
|
||||||
WSETUFLAG(wwin, dont_focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
|
WSETUFLAG(wwin, focus_across_wksp, WMGetButtonSelected(panel->moreChk[9]));
|
||||||
#ifdef XKB_BUTTON_HINT
|
#ifdef XKB_BUTTON_HINT
|
||||||
WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[10]));
|
WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[10]));
|
||||||
#endif
|
#endif
|
||||||
@@ -951,7 +951,7 @@ static void revertSettings(WMButton * button, InspectorPanel * panel)
|
|||||||
flag = WFLAGP(wwin, emulate_appicon);
|
flag = WFLAGP(wwin, emulate_appicon);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
flag = WFLAGP(wwin, dont_focus_across_wksp);
|
flag = WFLAGP(wwin, focus_across_wksp);
|
||||||
break;
|
break;
|
||||||
#ifdef XKB_BUTTON_HINT
|
#ifdef XKB_BUTTON_HINT
|
||||||
case 10:
|
case 10:
|
||||||
@@ -1394,11 +1394,10 @@ static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int yp
|
|||||||
"application icon to be created.");
|
"application icon to be created.");
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
caption = _("Don't focus across workspaces");
|
caption = _("Focus across workspaces");
|
||||||
flag = WFLAGP(wwin, dont_focus_across_wksp);
|
flag = WFLAGP(wwin, focus_across_wksp);
|
||||||
descr = _("Do not allow Window Maker to switch workspace to satisfy\n"
|
descr = _("Allow Window Maker to switch workspace to satisfy\n"
|
||||||
"a focus request (useful e.g. in the case of a multiple-tab\n"
|
"a focus request (annoying).");
|
||||||
"firefox opening in a different workspace).");
|
|
||||||
break;
|
break;
|
||||||
#ifdef XKB_BUTTON_HINT
|
#ifdef XKB_BUTTON_HINT
|
||||||
case 10:
|
case 10:
|
||||||
|
|||||||
36
src/wmspec.c
36
src/wmspec.c
@@ -35,6 +35,7 @@
|
|||||||
#include <X11/Xarch.h>
|
#include <X11/Xarch.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <WINGs/WUtil.h>
|
||||||
#include "WindowMaker.h"
|
#include "WindowMaker.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
@@ -49,10 +50,6 @@
|
|||||||
#include "xinerama.h"
|
#include "xinerama.h"
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
|
|
||||||
#ifdef DEBUG_WMSPEC
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern Atom _XA_WM_DELETE_WINDOW;
|
extern Atom _XA_WM_DELETE_WINDOW;
|
||||||
extern Time LastTimestamp;
|
extern Time LastTimestamp;
|
||||||
@@ -519,7 +516,7 @@ void wNETWMInitStuff(WScreen * scr)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef DEBUG_WMSPEC
|
#ifdef DEBUG_WMSPEC
|
||||||
printf("wNETWMInitStuff\n");
|
wmessage("enter");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_XINTERNATOMS
|
#ifdef HAVE_XINTERNATOMS
|
||||||
@@ -1041,7 +1038,7 @@ static void doStateAtom(WWindow * wwin, Atom state, int set, Bool init)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_WMSPEC
|
#ifdef DEBUG_WMSPEC
|
||||||
printf("doStateAtom unknown atom %s set %d\n", XGetAtomName(dpy, state), set);
|
wmessage("doStateAtom unknown atom %s set %d\n", XGetAtomName(dpy, state), set);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1303,7 +1300,7 @@ Bool wNETWMCheckInitialClientState(WWindow * wwin)
|
|||||||
Bool hasState = False;
|
Bool hasState = False;
|
||||||
|
|
||||||
#ifdef DEBUG_WMSPEC
|
#ifdef DEBUG_WMSPEC
|
||||||
printf("CheckInitialClientState\n");
|
wmessage("enter");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wNETWMShowingDesktop(wwin->screen_ptr, False);
|
wNETWMShowingDesktop(wwin->screen_ptr, False);
|
||||||
@@ -1354,7 +1351,7 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event)
|
|||||||
Bool done = True;
|
Bool done = True;
|
||||||
|
|
||||||
#ifdef DEBUG_WMSPEC
|
#ifdef DEBUG_WMSPEC
|
||||||
printf("processClientMessage type %s\n", XGetAtomName(dpy, event->message_type));
|
wmessage("processClientMessage type %s\n", XGetAtomName(dpy, event->message_type));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
scr = wScreenForWindow(event->window);
|
scr = wScreenForWindow(event->window);
|
||||||
@@ -1403,16 +1400,17 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event)
|
|||||||
|
|
||||||
if (event->message_type == net_active_window) {
|
if (event->message_type == net_active_window) {
|
||||||
/*
|
/*
|
||||||
* Firefox sends aditional 'net_active_window' signals on startup if
|
* Satisfy a client's focus request only if
|
||||||
* multiple tabs are open. That causes unnecessary workspace switching if
|
* - request comes from a pager, or
|
||||||
* those signals come from other workspaces. Therefore we also check if
|
* - it's explicitly allowed in Advanced Options, or
|
||||||
* we should ignore these spurious focus across workspaces requests (but
|
* - giving the client the focus does not cause a change in
|
||||||
* allow the switching if it comes from a pager).
|
* the active workspace (XXX: or the active head if Xinerama)
|
||||||
*/
|
*/
|
||||||
if (wwin->frame->workspace == wwin->screen_ptr->current_workspace
|
if (wwin->frame->workspace == wwin->screen_ptr->current_workspace /* No workspace change */
|
||||||
|| !WFLAGP(wwin, dont_focus_across_wksp) || event->data.l[0] == 2) {
|
|| event->data.l[0] == 2 /* Requested by pager */
|
||||||
wNETWMShowingDesktop(scr, False);
|
|| WFLAGP(wwin, focus_across_wksp) /* Explicitly allowed */) {
|
||||||
wMakeWindowVisible(wwin);
|
wNETWMShowingDesktop(scr, False);
|
||||||
|
wMakeWindowVisible(wwin);
|
||||||
}
|
}
|
||||||
} else if (event->message_type == net_close_window) {
|
} else if (event->message_type == net_close_window) {
|
||||||
if (!WFLAGP(wwin, no_closable)) {
|
if (!WFLAGP(wwin, no_closable)) {
|
||||||
@@ -1424,7 +1422,7 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event)
|
|||||||
long set = event->data.l[0];
|
long set = event->data.l[0];
|
||||||
|
|
||||||
#ifdef DEBUG_WMSPEC
|
#ifdef DEBUG_WMSPEC
|
||||||
printf("net_wm_state set %ld a1 %s a2 %s\n", set,
|
wmessage("net_wm_state set %ld a1 %s a2 %s\n", set,
|
||||||
XGetAtomName(dpy, event->data.l[1]), XGetAtomName(dpy, event->data.l[2]));
|
XGetAtomName(dpy, event->data.l[1]), XGetAtomName(dpy, event->data.l[2]));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1464,7 +1462,7 @@ Bool wNETWMCheckClientHintChange(WWindow * wwin, XPropertyEvent * event)
|
|||||||
Bool ret = True;
|
Bool ret = True;
|
||||||
|
|
||||||
#ifdef DEBUG_WMSPEC
|
#ifdef DEBUG_WMSPEC
|
||||||
printf("clientHintChange type %s\n", XGetAtomName(dpy, event->atom));
|
wmessage("clientHintChange type %s\n", XGetAtomName(dpy, event->atom));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (event->atom == net_wm_strut) {
|
if (event->atom == net_wm_strut) {
|
||||||
|
|||||||
Reference in New Issue
Block a user