diff --git a/src/actions.c b/src/actions.c index 565761fe..ce27b36f 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1621,7 +1621,7 @@ wArrangeIcons(WScreen *scr, Bool arrangeAll) pi = 0; si = 0; while (aicon) { - if (!aicon->docked && wAppIconIndexOfInstance(aicon) == 0) { + if (!aicon->docked && wAppIconIsFirstInstance(aicon)) { if (aicon->x_pos != X || aicon->y_pos != Y) { #ifdef ANIMATIONS if (!wPreferences.no_animations) { diff --git a/src/appicon.c b/src/appicon.c index 4cfcb834..56de20e8 100644 --- a/src/appicon.c +++ b/src/appicon.c @@ -277,20 +277,29 @@ drawCorner(WIcon *icon) void wAppIconMove(WAppIcon *aicon, int x, int y) { + WApplication *app; WAppIcon *tmp; - tmp = aicon->icon->core->screen_ptr->app_icon_list; + app = wApplicationOf(aicon->icon->owner->main_window); + + if (!WFLAGP(app->main_window_desc, collapse_appicons)) { + XMoveWindow(dpy, aicon->icon->core->window, x, y); + aicon->x_pos = x; + aicon->y_pos = y; + } else { + tmp = aicon->icon->core->screen_ptr->app_icon_list; - /* move all icons of the same class/name to the same pos */ - while (tmp) { - if (strcmp(tmp->wm_class, aicon->wm_class) == 0 && - strcmp(tmp->wm_instance, aicon->wm_instance) == 0 && - !tmp->docked) { - XMoveWindow(dpy, tmp->icon->core->window, x, y); - tmp->x_pos = x; - tmp->y_pos = y; + /* move all icons of the same class/name to the same pos */ + while (tmp) { + if (strcmp(tmp->wm_class, aicon->wm_class) == 0 && + strcmp(tmp->wm_instance, aicon->wm_instance) == 0 && + !tmp->docked) { + XMoveWindow(dpy, tmp->icon->core->window, x, y); + tmp->x_pos = x; + tmp->y_pos = y; + } + tmp = tmp->next; } - tmp = tmp->next; } } @@ -335,9 +344,16 @@ updateDockNumbers(WScreen *scr) WAppIcon* wAppIconNextSibling(WAppIcon *icon) -{ +{ + WApplication *app; WAppIcon *tmp; + app = wApplicationOf(icon->icon->owner->main_window); + + if (!WFLAGP(app->main_window_desc, collapse_appicons)) { + return NULL; + } + tmp = icon->next; while (tmp) { if (strcmp(tmp->wm_class, icon->wm_class) == 0 @@ -362,23 +378,26 @@ wAppIconNextSibling(WAppIcon *icon) } -int -wAppIconIndexOfInstance(WAppIcon *icon) +Bool +wAppIconIsFirstInstance(WAppIcon *icon) { WAppIcon *list = icon->icon->core->screen_ptr->app_icon_list; int index = 0; + + if (!WFLAGP(icon->icon->owner, collapse_appicons)) + return False; while (list) { if (icon == list) - return index; - + return True; + if (strcmp(icon->wm_instance, list->wm_instance) == 0 && strcmp(icon->wm_class, list->wm_class) == 0 && !icon->docked) - index++; + return False; list = list->next; } @@ -431,7 +450,7 @@ wAppIconPaint(WAppIcon *aicon) #endif /* HIDDENDOT */ if (wapp) - index = wApplicationIndexOfInstance(wapp); + index = wApplicationIndexOfGroup(wapp); else index = 0; @@ -485,6 +504,16 @@ unhideHereCallback(WMenu *menu, WMenuEntry *entry) } +static void +collapseCallback(WMenu *menu, WMenuEntry *entry) +{ + WApplication *wapp = (WApplication*)entry->clientdata; + + wApplicationSetCollapse(wapp, + !WFLAGP(wapp->main_window_desc, collapse_appicons)); +} + + static void setIconCallback(WMenu *menu, WMenuEntry *entry) { @@ -566,6 +595,7 @@ createApplicationMenu(WScreen *scr) menu = wMenuCreate(scr, NULL, False); wMenuAddCallback(menu, _("Unhide Here"), unhideHereCallback, NULL); wMenuAddCallback(menu, _("Hide"), hideCallback, NULL); + wMenuAddCallback(menu, _("Collapse"), collapseCallback, NULL); wMenuAddCallback(menu, _("Set Icon..."), setIconCallback, NULL); wMenuAddCallback(menu, _("Kill"), killCallback, NULL); @@ -593,6 +623,12 @@ openApplicationMenu(WApplication *wapp, int x, int y) menu->entries[1]->text = _("Hide"); } + if (WFLAGP(wapp->main_window_desc, collapse_appicons)) { + menu->entries[2]->text = _("Uncollapse"); + } else { + menu->entries[2]->text = _("Collapse"); + } + menu->flags.realized = 0; wMenuRealize(menu); @@ -716,6 +752,15 @@ appIconMouseDown(WObjDescriptor *desc, XEvent *event) wRaiseFrame(icon->core); + if (clickButton == Button2) { + WAppIcon *next = wAppIconNextSibling(aicon); + + if (next) { + wRaiseFrame(next->icon->core); + } + return; + } + if (XGrabPointer(dpy, icon->core->window, True, ButtonMotionMask |ButtonReleaseMask|ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime) !=GrabSuccess) { @@ -739,19 +784,6 @@ appIconMouseDown(WObjDescriptor *desc, XEvent *event) ghost); XClearWindow(dpy, scr->dock_shadow); } - - if (clickButton != Button1) { - done = True; - - if (clickButton == Button2) { - WAppIcon *next = wAppIconNextSibling(aicon); - - if (next) { - XRaiseWindow(dpy, next->icon->core->window); - XFlush(dpy); - } - } - } while (!done) { WMMaskEvent(dpy, PointerMotionMask|ButtonReleaseMask|ButtonPressMask diff --git a/src/appicon.h b/src/appicon.h index 61b224b9..9babdd00 100644 --- a/src/appicon.h +++ b/src/appicon.h @@ -96,5 +96,6 @@ void wAppIconMove(WAppIcon *aicon, int x, int y); WAppIcon *wAppIconNextSibling(WAppIcon *icon); -int wAppIconIndexOfInstance(WAppIcon *icon); +Bool wAppIconIsFirstInstance(WAppIcon *icon); + #endif diff --git a/src/application.c b/src/application.c index 9d945dbb..5b3a6649 100644 --- a/src/application.c +++ b/src/application.c @@ -493,16 +493,50 @@ wApplicationDestroy(WApplication *wapp) } + +void +wApplicationSetCollapse(WApplication *app, Bool flag) +{ + WApplication *list = app->main_window_desc->screen_ptr->wapp_list; + int index = 0; + WWindow *wwin = app->main_window_desc; + + if (WFLAGP(app->main_window_desc, collapse_appicons) == flag) + return; + + + while (list) { + if (strcmp(wwin->wm_instance, + list->main_window_desc->wm_instance) == 0 + && + strcmp(wwin->wm_class, + list->main_window_desc->wm_class) == 0) + WSETUFLAG(list->main_window_desc, collapse_appicons, flag); + + list = list->next; + } + + if (app->app_icon && flag) + wAppIconMove(app->app_icon, app->app_icon->x_pos, app->app_icon->y_pos); +} + + + + /* * Returns index number of the app in case there are more than * one instance of the same class/name. */ int -wApplicationIndexOfInstance(WApplication *app) +wApplicationIndexOfGroup(WApplication *app) { WApplication *list = app->main_window_desc->screen_ptr->wapp_list; int index = 0; WWindow *wwin = app->main_window_desc; +/* + if (!WFLAGP(wwin, collapse_appicons)) + return 0; + */ while (list) { if (app == list) @@ -523,28 +557,3 @@ wApplicationIndexOfInstance(WApplication *app) return 0; } - -Bool -wApplicationHasMultiInstances(WApplication *app) -{ - WApplication *list = app->main_window_desc->screen_ptr->wapp_list; - int index = 0; - WWindow *wwin = app->main_window_desc; - - while (list) { - if (strcmp(wwin->wm_instance, - list->main_window_desc->wm_instance) == 0 - && - strcmp(wwin->wm_class, - list->main_window_desc->wm_class) == 0) - index++; - - if (index == 2) - return True; - - list = list->next; - } - - return False; -} - diff --git a/src/application.h b/src/application.h index 38398eb6..9d80667c 100644 --- a/src/application.h +++ b/src/application.h @@ -55,13 +55,12 @@ void wApplicationDestroy(WApplication *wapp); WApplication *wApplicationOf(Window window); -Bool wApplicationHasMultiInstances(WApplication *app); - void wApplicationExtractDirPackIcon(WScreen *scr,char *path, char *wm_instance, char *wm_class); -int wApplicationIndexOfInstance(WApplication *app); +int wApplicationIndexOfGroup(WApplication *app); +void wApplicationSetCollapse(WApplication *app, Bool flag); #ifdef NEWAPPICON diff --git a/src/wdefaults.c b/src/wdefaults.c index c3c29a35..0f65e852 100644 --- a/src/wdefaults.c +++ b/src/wdefaults.c @@ -84,6 +84,7 @@ static proplist_t AStartHidden; /* app */ static proplist_t ADontSaveSession; /* app */ static proplist_t AEmulateAppIcon; static proplist_t AFullMaximize; +static proplist_t ACollapseAppIcons; /* app */ #ifdef XKB_BUTTON_HINT static proplist_t ANoLanguageButton; #endif @@ -124,6 +125,7 @@ init_wdefaults(WScreen *scr) ADontSaveSession = PLMakeString("DontSaveSession"); AEmulateAppIcon = PLMakeString("EmulateAppIcon"); AFullMaximize = PLMakeString("FullMaximize"); + ACollapseAppIcons = PLMakeString("CollapseAppIcons"); #ifdef XKB_BUTTON_HINT ANoLanguageButton = PLMakeString("NoLanguageButton"); #endif @@ -278,6 +280,9 @@ wDefaultFillAttributes(WScreen *scr, char *instance, char *class, value = get_value(dw, dc, dn, da, ANoAppIcon, No, useGlobalDefault); APPLY_VAL(value, no_appicon, ANoAppIcon); + value = get_value(dw, dc, dn, da, ACollapseAppIcons, No, useGlobalDefault); + APPLY_VAL(value, collapse_appicons, ACollapseAppIcons); + value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault); APPLY_VAL(value, floating, AKeepOnTop); diff --git a/src/window.c b/src/window.c index 6c458875..593b6943 100644 --- a/src/window.c +++ b/src/window.c @@ -1772,7 +1772,7 @@ wWindowUpdateName(WWindow *wwin, char *newTitle) return; if (app) - instIndex = wApplicationIndexOfInstance(app); + instIndex = wApplicationIndexOfGroup(app); wwin->flags.wm_name_changed = 1; diff --git a/src/window.h b/src/window.h index 12b88c2d..9030b72c 100644 --- a/src/window.h +++ b/src/window.h @@ -118,7 +118,9 @@ typedef struct { * is focused */ unsigned int no_hide_others:1; /* hide window when doing hideothers */ unsigned int no_appicon:1; /* make app icon */ - + + unsigned int collapse_appicons:1; /* collapse icons of the same name */ + unsigned int dont_move_off:1; unsigned int no_focusable:1; diff --git a/src/winspector.c b/src/winspector.c index 139381b2..88a04a72 100644 --- a/src/winspector.c +++ b/src/winspector.c @@ -114,7 +114,7 @@ typedef struct InspectorPanel { /* 5th page. application wide attributes */ WMFrame *appFrm; - WMButton *appChk[2]; + WMButton *appChk[3]; unsigned int done:1; unsigned int destroyed:1; @@ -153,6 +153,7 @@ static proplist_t AStartMaximized; static proplist_t ADontSaveSession; static proplist_t AEmulateAppIcon; static proplist_t AFullMaximize; +static proplist_t ACollapseAppIcons; #ifdef XKB_BUTTON_HINT static proplist_t ANoLanguageButton; #endif @@ -220,6 +221,7 @@ make_keys() ADontSaveSession = PLMakeString("DontSaveSession"); AEmulateAppIcon = PLMakeString("EmulateAppIcon"); AFullMaximize = PLMakeString("FullMaximize"); + ACollapseAppIcons = PLMakeString("CollapseAppIcons"); #ifdef XKB_BUTTON_HINT ANoLanguageButton = PLMakeString("NoLanguageButton"); #endif @@ -658,6 +660,9 @@ saveSettings(WMButton *button, InspectorPanel *panel) value = (WMGetButtonSelected(panel->appChk[1])!=0) ? Yes : No; different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags); + + value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No; + different |= insertAttribute(dict, winDic, ACollapseAppIcons, value, flags); } PLRemoveDictionaryEntry(dict, key); @@ -713,6 +718,10 @@ saveSettings(WMButton *button, InspectorPanel *panel) different |= insertAttribute(dict, appDic, ANoAppIcon, value, flags); + value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No; + different |= insertAttribute(dict, appDic, ACollapseAppIcons, value, + flags); + PLRemoveDictionaryEntry(dict, key); if (different) { PLInsertDictionaryEntry(dict, key, appDic); @@ -896,6 +905,9 @@ applySettings(WMButton *button, InspectorPanel *panel) WSETUFLAG(wapp->main_window_desc, no_appicon, WMGetButtonSelected(panel->appChk[1])); + + WSETUFLAG(wapp->main_window_desc, collapse_appicons, + WMGetButtonSelected(panel->appChk[2])); if (WFLAGP(wapp->main_window_desc, no_appicon)) removeAppIconFor(wapp); @@ -1031,6 +1043,9 @@ revertSettings(WMButton *button, InspectorPanel *panel) case 1: flag = WFLAGP(wapp->main_window_desc, no_appicon); break; + case 2: + flag = WFLAGP(wapp->main_window_desc, collapse_appicons); + break; } WMSetButtonSelected(panel->appChk[i], flag); } @@ -1576,7 +1591,7 @@ createInspectorForWindow(WWindow *wwin, int xpos, int ypos, WMMoveWidget(panel->appFrm, 15, 50); WMResizeWidget(panel->appFrm, frame_width, 240); - for (i=0; i < 2; i++) { + for (i=0; i < 3; i++) { char *caption = NULL; int flag = 0; char *descr = NULL; @@ -1595,6 +1610,12 @@ createInspectorForWindow(WWindow *wwin, int xpos, int ypos, "and any icons that are already docked will stop\n" "working correctly."); break; + case 2: + caption = _("Collapse Application Icons"); + flag = WFLAGP(wapp->main_window_desc, collapse_appicons); + descr = _("Collapse application icons from other instances\n" + "of this application into one.\n"); + break; } panel->appChk[i] = WMCreateSwitchButton(panel->appFrm); WMMoveWidget(panel->appChk[i], 10, 20*(i+1));