diff --git a/src/session.c b/src/session.c index 90f50405..17a2d5a7 100644 --- a/src/session.c +++ b/src/session.c @@ -803,7 +803,7 @@ static WMPropList *makeAttributeState(WWindow * wwin) ? (wwin)->user_flags.FLAG : -1) snprintf(buffer, sizeof(buffer), - "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", + "%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", W_FLAG(no_titlebar), W_FLAG(no_resizable), W_FLAG(no_closable), @@ -827,7 +827,8 @@ static WMPropList *makeAttributeState(WWindow * wwin) W_FLAG(always_user_icon), W_FLAG(start_miniaturized), W_FLAG(start_hidden), - W_FLAG(start_maximized), W_FLAG(dont_save_session), W_FLAG(emulate_appicon)); + W_FLAG(start_maximized), + W_FLAG(dont_save_session), W_FLAG(dont_focus_across_wksp), W_FLAG(emulate_appicon)); return WMCreatePLString(buffer); } diff --git a/src/wdefaults.c b/src/wdefaults.c index d82bb49a..5fec333e 100644 --- a/src/wdefaults.c +++ b/src/wdefaults.c @@ -78,6 +78,7 @@ static WMPropList *AStartMaximized; static WMPropList *AStartHidden; /* app */ static WMPropList *ADontSaveSession; /* app */ static WMPropList *AEmulateAppIcon; +static WMPropList *ADontFocusAcrossWorkspace; static WMPropList *AFullMaximize; static WMPropList *ASharedAppIcon; /* app */ #ifdef XKB_BUTTON_HINT @@ -116,6 +117,7 @@ static void init_wdefaults(WScreen * scr) AStartMaximized = WMCreatePLString("StartMaximized"); ADontSaveSession = WMCreatePLString("DontSaveSession"); AEmulateAppIcon = WMCreatePLString("EmulateAppIcon"); + ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace"); AFullMaximize = WMCreatePLString("FullMaximize"); ASharedAppIcon = WMCreatePLString("SharedAppIcon"); #ifdef XKB_BUTTON_HINT @@ -304,6 +306,9 @@ 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, AFullMaximize, No, useGlobalDefault); APPLY_VAL(value, full_maximize, AFullMaximize); diff --git a/src/window.h b/src/window.h index e8275e25..f729fd9c 100644 --- a/src/window.h +++ b/src/window.h @@ -125,6 +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 always_user_icon:1; /* ignore client IconPixmap or * IconWindow */ diff --git a/src/winspector.c b/src/winspector.c index 4609a7e3..fe473c2f 100644 --- a/src/winspector.c +++ b/src/winspector.c @@ -93,9 +93,9 @@ typedef struct InspectorPanel { /* 3rd page. more attributes */ WMFrame *moreFrm; #ifdef XKB_BUTTON_HINT - WMButton *moreChk[9]; + WMButton *moreChk[10]; #else - WMButton *moreChk[8]; + WMButton *moreChk[9]; #endif /* 4th page. icon and workspace */ @@ -144,6 +144,7 @@ static WMPropList *AOmnipresent; static WMPropList *ASkipWindowList; static WMPropList *AKeepInsideScreen; static WMPropList *AUnfocusable; +static WMPropList *ADontFocusAcrossWorkspace; static WMPropList *AAlwaysUserIcon; static WMPropList *AStartMiniaturized; static WMPropList *AStartMaximized; @@ -198,6 +199,7 @@ static void make_keys() ASkipWindowList = WMCreatePLString("SkipWindowList"); AKeepInsideScreen = WMCreatePLString("KeepInsideScreen"); AUnfocusable = WMCreatePLString("Unfocusable"); + ADontFocusAcrossWorkspace = WMCreatePLString("DontFocusAcrossWorkspace"); AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon"); AStartMiniaturized = WMCreatePLString("StartMiniaturized"); AStartMaximized = WMCreatePLString("StartMaximized"); @@ -598,8 +600,11 @@ static void saveSettings(WMButton * button, InspectorPanel * panel) value = (WMGetButtonSelected(panel->moreChk[7]) != 0) ? Yes : No; different |= insertAttribute(dict, winDic, AEmulateAppIcon, value, flags); -#ifdef XKB_BUTTON_HINT value = (WMGetButtonSelected(panel->moreChk[8]) != 0) ? Yes : No; + different |= insertAttribute(dict, winDic, ADontFocusAcrossWorkspace, value, flags); + +#ifdef XKB_BUTTON_HINT + value = (WMGetButtonSelected(panel->moreChk[9]) != 0) ? Yes : No; different |= insertAttribute(dict, winDic, ANoLanguageButton, value, flags); #endif @@ -751,6 +756,7 @@ static void applySettings(WMButton * button, InspectorPanel * panel) showIconFor(WMWidgetScreen(button), panel, NULL, NULL, USE_TEXT_FIELD); + /* Attributes... --> Window Attributes */ WSETUFLAG(wwin, no_titlebar, WMGetButtonSelected(panel->attrChk[0])); WSETUFLAG(wwin, no_resizebar, WMGetButtonSelected(panel->attrChk[1])); WSETUFLAG(wwin, no_close_button, WMGetButtonSelected(panel->attrChk[2])); @@ -763,6 +769,7 @@ static void applySettings(WMButton * button, InspectorPanel * panel) WSETUFLAG(wwin, start_maximized, WMGetButtonSelected(panel->attrChk[9])); WSETUFLAG(wwin, full_maximize, WMGetButtonSelected(panel->attrChk[10])); + /* Attributes... --> Advanced Options */ WSETUFLAG(wwin, no_bind_keys, WMGetButtonSelected(panel->moreChk[0])); WSETUFLAG(wwin, no_bind_mouse, WMGetButtonSelected(panel->moreChk[1])); skip_window_list = WMGetButtonSelected(panel->moreChk[2]); @@ -771,8 +778,9 @@ static void applySettings(WMButton * button, InspectorPanel * panel) WSETUFLAG(wwin, no_hide_others, WMGetButtonSelected(panel->moreChk[5])); WSETUFLAG(wwin, dont_save_session, WMGetButtonSelected(panel->moreChk[6])); WSETUFLAG(wwin, emulate_appicon, WMGetButtonSelected(panel->moreChk[7])); + WSETUFLAG(wwin, dont_focus_across_wksp, WMGetButtonSelected(panel->moreChk[8])); #ifdef XKB_BUTTON_HINT - WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[8])); + WSETUFLAG(wwin, no_language_button, WMGetButtonSelected(panel->moreChk[9])); #endif WSETUFLAG(wwin, always_user_icon, WMGetButtonSelected(panel->alwChk)); @@ -919,7 +927,7 @@ static void revertSettings(WMButton * button, InspectorPanel * panel) } WMSetButtonSelected(panel->attrChk[i], flag); } - for (i = 0; i < 8; i++) { + for (i = 0; i < 9; i++) { int flag = 0; switch (i) { @@ -947,8 +955,11 @@ static void revertSettings(WMButton * button, InspectorPanel * panel) case 7: flag = WFLAGP(wwin, emulate_appicon); break; -#ifdef XKB_BUTTON_HINT case 8: + flag = WFLAGP(wwin, dont_focus_across_wksp); + break; +#ifdef XKB_BUTTON_HINT + case 9: flag = WFLAGP(wwin, no_language_button); break; #endif @@ -1323,9 +1334,9 @@ static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int yp for (i = 0; #ifdef XKB_BUTTON_HINT - i < 9; + i < 10; #else - i < 8; + i < 9; #endif i++) { char *caption = NULL; @@ -1382,8 +1393,15 @@ static InspectorPanel *createInspectorForWindow(WWindow * wwin, int xpos, int yp "enough information to Window Maker for a dockable\n" "application icon to be created."); break; -#ifdef XKB_BUTTON_HINT case 8: + 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)."); + break; +#ifdef XKB_BUTTON_HINT + case 9: caption = _("Disable language button"); flag = WFLAGP(wwin, no_language_button); descr = _("Remove the `toggle language' button of the window."); diff --git a/src/wmspec.c b/src/wmspec.c index ab4ddcf9..302aa982 100644 --- a/src/wmspec.c +++ b/src/wmspec.c @@ -1448,15 +1448,19 @@ Bool wNETWMProcessClientMessage(XClientMessageEvent * event) if (!wwin) return False; - /* - * Firefox with multiple tabs sends aditional 'net_active_window' - * signals on startup, which causes unnecessary workspace switching - * if its initial workspace is different from the current - */ - if (event->message_type == net_active_window && - wwin->frame->workspace == wwin->screen_ptr->current_workspace) { - wNETWMShowingDesktop(scr, False); - wMakeWindowVisible(wwin); + 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). + */ + 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); + } } else if (event->message_type == net_close_window) { if (!WFLAGP(wwin, no_closable)) { if (wwin->protocols.DELETE_WINDOW)