From f6fefbd9b6c6d22b13a22a22955478395933e615 Mon Sep 17 00:00:00 2001 From: Tamas TEVESZ Date: Mon, 18 Apr 2011 21:00:49 +0200 Subject: [PATCH] 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"). --- src/wdefaults.c | 8 ++++---- src/window.h | 4 ++-- src/winspector.c | 19 +++++++++---------- src/wmspec.c | 36 +++++++++++++++++------------------- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/wdefaults.c b/src/wdefaults.c index ffe3b20a..94487d0d 100644 --- a/src/wdefaults.c +++ b/src/wdefaults.c @@ -74,7 +74,7 @@ static WMPropList *AStartMaximized; static WMPropList *AStartHidden; /* app */ static WMPropList *ADontSaveSession; /* app */ static WMPropList *AEmulateAppIcon; -static WMPropList *ADontFocusAcrossWorkspace; +static WMPropList *AFocusAcrossWorkspace; static WMPropList *AFullMaximize; static WMPropList *ASharedAppIcon; /* app */ #ifdef XKB_BUTTON_HINT @@ -111,7 +111,7 @@ static void init_wdefaults(WScreen * scr) AStartMaximized = WMCreatePLString("StartMaximized"); ADontSaveSession = WMCreatePLString("DontSaveSession"); AEmulateAppIcon = WMCreatePLString("EmulateAppIcon"); - ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace"); + AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace"); AFullMaximize = WMCreatePLString("FullMaximize"); ASharedAppIcon = WMCreatePLString("SharedAppIcon"); #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); APPLY_VAL(value, emulate_appicon, AEmulateAppIcon); - value = get_value(dw, dc, dn, da, ADontFocusAcrossWorkspace, No, useGlobalDefault); - APPLY_VAL(value, dont_focus_across_wksp, ADontFocusAcrossWorkspace); + value = get_value(dw, dc, dn, da, AFocusAcrossWorkspace, No, useGlobalDefault); + APPLY_VAL(value, focus_across_wksp, AFocusAcrossWorkspace); value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault); APPLY_VAL(value, full_maximize, AFullMaximize); diff --git a/src/window.h b/src/window.h index 47c25066..edebe809 100644 --- a/src/window.h +++ b/src/window.h @@ -125,8 +125,8 @@ typedef struct { unsigned int dont_move_off:1; unsigned int no_focusable:1; - unsigned int dont_focus_across_wksp:1; /* don't let wmaker switch workspace to follow - * a focus request */ + unsigned int focus_across_wksp:1; /* let wmaker switch workspace to follow + * a focus request */ unsigned int always_user_icon:1; /* ignore client IconPixmap or * IconWindow */ diff --git a/src/winspector.c b/src/winspector.c index 8b140948..7efe99f1 100644 --- a/src/winspector.c +++ b/src/winspector.c @@ -138,7 +138,7 @@ static WMPropList *ASkipWindowList; static WMPropList *ASkipSwitchPanel; static WMPropList *AKeepInsideScreen; static WMPropList *AUnfocusable; -static WMPropList *ADontFocusAcrossWorkspace; +static WMPropList *AFocusAcrossWorkspace; static WMPropList *AAlwaysUserIcon; static WMPropList *AStartMiniaturized; static WMPropList *AStartMaximized; @@ -190,7 +190,7 @@ static void make_keys(void) ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel"); AKeepInsideScreen = WMCreatePLString("KeepInsideScreen"); AUnfocusable = WMCreatePLString("Unfocusable"); - ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace"); + AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace"); AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon"); AStartMiniaturized = WMCreatePLString("StartMiniaturized"); AStartMaximized = WMCreatePLString("StartMaximized"); @@ -595,7 +595,7 @@ static void saveSettings(WMButton * button, InspectorPanel * panel) different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags); 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 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, dont_save_session, WMGetButtonSelected(panel->moreChk[7])); 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 WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[10])); #endif @@ -951,7 +951,7 @@ static void revertSettings(WMButton * button, InspectorPanel * panel) flag = WFLAGP(wwin, emulate_appicon); break; case 9: - flag = WFLAGP(wwin, dont_focus_across_wksp); + flag = WFLAGP(wwin, focus_across_wksp); break; #ifdef XKB_BUTTON_HINT case 10: @@ -1394,11 +1394,10 @@ static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int yp "application icon to be created."); break; case 9: - caption = _("Don't focus across workspaces"); - flag = WFLAGP(wwin, dont_focus_across_wksp); - descr = _("Do not allow Window Maker to switch workspace to satisfy\n" - "a focus request (useful e.g. in the case of a multiple-tab\n" - "firefox opening in a different workspace)."); + caption = _("Focus across workspaces"); + flag = WFLAGP(wwin, focus_across_wksp); + descr = _("Allow Window Maker to switch workspace to satisfy\n" + "a focus request (annoying)."); break; #ifdef XKB_BUTTON_HINT case 10: diff --git a/src/wmspec.c b/src/wmspec.c index d3bce77c..95985dba 100644 --- a/src/wmspec.c +++ b/src/wmspec.c @@ -35,6 +35,7 @@ #include #include +#include #include "WindowMaker.h" #include "window.h" #include "screen.h" @@ -49,10 +50,6 @@ #include "xinerama.h" #include "properties.h" -#ifdef DEBUG_WMSPEC -#include -#endif - /* Global variables */ extern Atom _XA_WM_DELETE_WINDOW; extern Time LastTimestamp; @@ -519,7 +516,7 @@ void wNETWMInitStuff(WScreen * scr) int i; #ifdef DEBUG_WMSPEC - printf("wNETWMInitStuff\n"); + wmessage("enter"); #endif #ifdef HAVE_XINTERNATOMS @@ -1041,7 +1038,7 @@ static void doStateAtom(WWindow * wwin, Atom state, int set, Bool init) } else { #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 } } @@ -1303,7 +1300,7 @@ Bool wNETWMCheckInitialClientState(WWindow * wwin) Bool hasState = False; #ifdef DEBUG_WMSPEC - printf("CheckInitialClientState\n"); + wmessage("enter"); #endif wNETWMShowingDesktop(wwin->screen_ptr, False); @@ -1354,7 +1351,7 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event) Bool done = True; #ifdef DEBUG_WMSPEC - printf("processClientMessage type %s\n", XGetAtomName(dpy, event->message_type)); + wmessage("processClientMessage type %s\n", XGetAtomName(dpy, event->message_type)); #endif scr = wScreenForWindow(event->window); @@ -1403,16 +1400,17 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event) if (event->message_type == net_active_window) { /* - * Firefox sends aditional 'net_active_window' signals on startup if - * multiple tabs are open. That causes unnecessary workspace switching if - * those signals come from other workspaces. Therefore we also check if - * we should ignore these spurious focus across workspaces requests (but - * allow the switching if it comes from a pager). + * Satisfy a client's focus request only if + * - request comes from a pager, or + * - it's explicitly allowed in Advanced Options, or + * - giving the client the focus does not cause a change in + * the active workspace (XXX: or the active head if Xinerama) */ - if (wwin->frame->workspace == wwin->screen_ptr->current_workspace - || !WFLAGP(wwin, dont_focus_across_wksp) || event->data.l[0] == 2) { - wNETWMShowingDesktop(scr, False); - wMakeWindowVisible(wwin); + if (wwin->frame->workspace == wwin->screen_ptr->current_workspace /* No workspace change */ + || event->data.l[0] == 2 /* Requested by pager */ + || WFLAGP(wwin, focus_across_wksp) /* Explicitly allowed */) { + wNETWMShowingDesktop(scr, False); + wMakeWindowVisible(wwin); } } else if (event->message_type == net_close_window) { if (!WFLAGP(wwin, no_closable)) { @@ -1424,7 +1422,7 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event) long set = event->data.l[0]; #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])); #endif @@ -1464,7 +1462,7 @@ Bool wNETWMCheckClientHintChange(WWindow * wwin, XPropertyEvent * event) Bool ret = True; #ifdef DEBUG_WMSPEC - printf("clientHintChange type %s\n", XGetAtomName(dpy, event->atom)); + wmessage("clientHintChange type %s\n", XGetAtomName(dpy, event->atom)); #endif if (event->atom == net_wm_strut) { -- 2.11.4.GIT