1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 20:38:08 +01:00

- removed the collapse appicons thing

- added real appicon sharing (apps of the same kind will have a single
  shared appicon).
This commit is contained in:
dan
2001-12-17 04:02:33 +00:00
parent 739fd1a567
commit 672c42cc48
19 changed files with 251 additions and 346 deletions

View File

@@ -24,6 +24,9 @@ Changes since version 0.70.0:
default.
- Mapping a new window that belongs to a running application that is hidden,
will unhide the application.
- Removed the collapse appicons thing.
- Added real appicon sharing (apps of the same kind will have a single shared
appicon).
Changes since version 0.65.1:

View File

@@ -373,7 +373,7 @@ extern const WMHashTableCallbacks WMStringHashCallbacks;
* and freed with wfree() */
extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
/* keys are strings, bug they are not copied */
/* keys are strings, but they are not copied */
/*......................................................................*/

View File

@@ -7,8 +7,8 @@
WSoundServer = {Icon = sound.#extension#;};
panel.Panel = {NoAppIcon = YES;};
gmc.Gmc = {NoAppIcon = YES;};
XTerm = {Icon = Terminal.#extension#;};
NXTerm = {Icon = Terminal.#extension#;};
XTerm = {SharedAppIcon = Yes;Icon = Terminal.#extension#;};
NXTerm = {SharedAppIcon = Yes;Icon = Terminal.#extension#;};
ScilabGraphic0.Xscilab = {KeepInsideScreen=YES;};
ScilabGraphic1.Xscilab = {KeepInsideScreen=YES;};
ScilabGraphic2.Xscilab = {KeepInsideScreen=YES;};
@@ -46,7 +46,7 @@
Xmag = {Icon = inspect.xpm;};
Xmessage = {Icon = Reference.xpm;};
XConsole = {Icon = inspect.xpm;Omnipresent = Yes;};
Fte = {Icon = Clipboard.xpm;};
Fte = {SharedAppIcon = Yes;Icon = Clipboard.tif;};
xjed = {Icon = Clipboard.xpm;};
xedit = {Icon = notepad.#extension#;};
xmixer = {Icon = mixer.#extension#;};

View File

@@ -15,7 +15,7 @@ AC_INIT(src/WindowMaker.h)
AM_INIT_AUTOMAKE(WindowMaker, 0.70.1)
AM_INIT_AUTOMAKE(WindowMaker, 0.80.0)
AM_PROG_LIBTOOL

View File

@@ -15,7 +15,7 @@ AC_INIT(src/WindowMaker.h)
AM_INIT_AUTOMAKE(WindowMaker, 0.70.1)
AM_INIT_AUTOMAKE(WindowMaker, 0.80.0)
AM_PROG_LIBTOOL

View File

@@ -1538,7 +1538,7 @@ wArrangeIcons(WScreen *scr, Bool arrangeAll)
pi = 0;
si = 0;
while (aicon) {
if (!aicon->docked && wAppIconIsFirstInstance(aicon)) {
if (!aicon->docked) {
if (aicon->x_pos != X || aicon->y_pos != Y) {
#ifdef ANIMATIONS
if (!wPreferences.no_animations) {

View File

@@ -278,29 +278,12 @@ void
wAppIconMove(WAppIcon *aicon, int x, int y)
{
WApplication *app;
WAppIcon *tmp;
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;
}
tmp = tmp->next;
}
}
XMoveWindow(dpy, aicon->icon->core->window, x, y);
aicon->x_pos = x;
aicon->y_pos = y;
}
@@ -341,79 +324,11 @@ updateDockNumbers(WScreen *scr)
#endif /* WS_INDICATOR */
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
&& strcmp(tmp->wm_instance, icon->wm_instance) == 0
&& !tmp->docked) {
return tmp;
}
tmp = tmp->next;
}
tmp = icon->icon->core->screen_ptr->app_icon_list;
while (tmp && tmp != icon) {
if (strcmp(tmp->wm_class, icon->wm_class) == 0
&& strcmp(tmp->wm_instance, icon->wm_instance) == 0
&& !tmp->docked) {
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
Bool
wAppIconIsFirstInstance(WAppIcon *icon)
{
WAppIcon *list = icon->icon->core->screen_ptr->app_icon_list;
if (!WFLAGP(icon->icon->owner, collapse_appicons))
return True;
while (list) {
if (icon == list)
return True;
if (strcmp(icon->wm_instance,
list->wm_instance) == 0
&&
strcmp(icon->wm_class,
list->wm_class) == 0
&& !icon->docked)
return False;
list = list->next;
}
puts("OH SHIT!?!?!? HOW THE FUCK DID WE GET HERE!?!?!?!?!");
return 0;
}
void
wAppIconPaint(WAppIcon *aicon)
{
WApplication *wapp;
WScreen *scr = aicon->icon->core->screen_ptr;
int index;
if (aicon->icon->owner)
wapp = wApplicationOf(aicon->icon->owner->main_window);
@@ -448,22 +363,6 @@ wAppIconPaint(WAppIcon *aicon)
}
#endif /* HIDDENDOT */
if (wapp)
index = wApplicationIndexOfGroup(wapp);
else
index = 0;
if (index > 0) {
char buf[16];
snprintf(buf, sizeof(buf), "%i", index);
WMDrawString(scr->wmscreen, aicon->icon->core->window,
scr->clip_title_gc, scr->title_font,
3, 3, buf, strlen(buf));
}
if (aicon->omnipresent)
drawCorner(aicon->icon);
@@ -503,16 +402,6 @@ 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)
{
@@ -557,6 +446,7 @@ static void
killCallback(WMenu *menu, WMenuEntry *entry)
{
WApplication *wapp = (WApplication*)entry->clientdata;
WFakeGroupLeader *fPtr;
char *buffer;
if (!WCHECK_STATE(WSTATE_NORMAL))
@@ -571,12 +461,26 @@ killCallback(WMenu *menu, WMenuEntry *entry)
"Any unsaved changes will be lost.\n"
"Please confirm."));
fPtr = wapp->main_window_desc->fake_group;
wretain(wapp->main_window_desc);
if (wPreferences.dont_confirm_kill
|| wMessageDialog(menu->frame->screen_ptr, _("Kill Application"),
buffer, _("Yes"), _("No"), NULL)==WAPRDefault) {
if (!wapp->main_window_desc->flags.destroyed)
wClientKill(wapp->main_window_desc);
if (fPtr!=NULL) {
WWindow *wwin, *twin;
wwin = wapp->main_window_desc->screen_ptr->focused_window;
while (wwin) {
twin = wwin->prev;
if (wwin->fake_group == fPtr) {
wClientKill(wwin);
}
wwin = twin;
}
} else if (!wapp->main_window_desc->flags.destroyed) {
wClientKill(wapp->main_window_desc);
}
}
wrelease(wapp->main_window_desc);
@@ -594,7 +498,6 @@ 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);
@@ -622,12 +525,6 @@ 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);
@@ -712,7 +609,7 @@ appIconMouseDown(WObjDescriptor *desc, XEvent *event)
if (aicon->editing || WCHECK_STATE(WSTATE_MODAL))
return;
if (event->xbutton.button == Button1 && IsDoubleClick(scr, event)) {
if (IsDoubleClick(scr, event)) {
iconDblClick(desc, event);
return;
}
@@ -750,16 +647,6 @@ appIconMouseDown(WObjDescriptor *desc, XEvent *event)
else
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) {
@@ -897,19 +784,10 @@ appIconMouseDown(WObjDescriptor *desc, XEvent *event)
wDockLower(workspace->clip);
if (!docked) {
/* If icon could not be docked, slide it back to the old
* position */
SlideWindow(icon->core->window, x, y, oldX, oldY);
} else {
WAppIcon *nextIcon = wAppIconNextSibling(aicon);
if (nextIcon) {
/* move the next instance back to the old position */
SlideWindow(nextIcon->icon->core->window, x, y,
oldX, oldY);
wAppIconMove(nextIcon, oldX, oldY);
}
}
/* If icon could not be docked, slide it back to the old
* position */
SlideWindow(icon->core->window, x, y, oldX, oldY);
}
wSoundPlay(WSOUND_DOCK);
} else {

View File

@@ -97,8 +97,4 @@ Bool wAppIconChangeImage(WAppIcon *icon, char *file);
void wAppIconMove(WAppIcon *aicon, int x, int y);
WAppIcon *wAppIconNextSibling(WAppIcon *icon);
Bool wAppIconIsFirstInstance(WAppIcon *icon);
#endif

View File

@@ -270,8 +270,13 @@ wApplicationCreate(WScreen *scr, Window main_window)
wapp = wApplicationOf(main_window);
if (wapp) {
wapp->refcount++;
return wapp;
wapp->refcount++;
if (wapp->app_icon && wapp->app_icon->docked &&
wapp->app_icon->relaunching && wapp->main_window_desc->fake_group) {
wDockFinishLaunch(wapp->app_icon->dock, wapp->app_icon);
}
return wapp;
}
wapp = wmalloc(sizeof(WApplication));
@@ -330,7 +335,7 @@ wApplicationCreate(WScreen *scr, Window main_window)
break;
}
}
if (wapp->app_icon) {
WWindow *mainw = wapp->main_window_desc;
@@ -413,56 +418,7 @@ wApplicationCreate(WScreen *scr, Window main_window)
if (!tmp)
extractClientIcon(wapp->app_icon);
}
/* set the application instance index */
{
WApplication *list = scr->wapp_list;
WApplication *prev = NULL;
int index = 0;
WWindow *wwin = wapp->main_window_desc;
/*
if (!WFLAGP(wwin, collapse_appicons))
return 0;
*/
#define Xstreql(a, b) ((a) == (b) || (a && b && strcmp(a, b)==0))
/* look for a free index # */
while (list) {
if (Xstreql(wwin->wm_instance,
list->main_window_desc->wm_instance)
&&
Xstreql(wwin->wm_class,
list->main_window_desc->wm_class)) {
if (list->index == index) {
index++;
/* restart list traversal */
list = scr->wapp_list;
prev = NULL;
continue;
}
}
prev = list;
list = list->next;
}
wapp->index = index;
wapp->next = NULL;
wapp->prev = NULL;
/* append to app list */
if (!prev) {
scr->wapp_list = wapp;
} else {
prev->next = wapp;
wapp->prev = prev;
}
}
wSoundPlay(WSOUND_APPSTART);
#ifdef DEBUG
@@ -545,41 +501,3 @@ wApplicationDestroy(WApplication *wapp)
void
wApplicationSetCollapse(WApplication *app, Bool flag)
{
WApplication *list = app->main_window_desc->screen_ptr->wapp_list;
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
wApplicationIndexOfGroup(WApplication *app)
{
return app->index;
}

View File

@@ -36,12 +36,10 @@ typedef struct WApplication {
struct WAppIcon *app_icon;
int index;
int refcount;
struct WWindow *last_focused; /* focused window before hide */
int last_workspace; /* last workspace used to work on the
* app */
struct {
@@ -60,10 +58,6 @@ WApplication *wApplicationOf(Window window);
void wApplicationExtractDirPackIcon(WScreen *scr,char *path, char *wm_instance,
char *wm_class);
int wApplicationIndexOfGroup(WApplication *app);
void wApplicationSetCollapse(WApplication *app, Bool flag);
#ifdef NEWAPPICON
# define wApplicationActivate(wapp) {\

View File

@@ -436,7 +436,11 @@ wClientCheckProperty(WWindow *wwin, XPropertyEvent *event)
i = 0;
}
}
if (wwin->fake_group!=NULL) {
i = 7;
}
if (wwin->wm_hints)
XFree(wwin->wm_hints);
@@ -475,7 +479,10 @@ wClientCheckProperty(WWindow *wwin, XPropertyEvent *event)
wwin->group_id = wwin->main_window;
wApplicationCreate(wwin->screen_ptr, wwin->main_window);
break;
}
/* 7 - we have a fake window group id, so just ignore anything else */
case 7:
break;
}
#ifdef DEBUG
if (i) {
printf("window leader update caused state transition %i\n",i);
@@ -504,8 +511,10 @@ wClientCheckProperty(WWindow *wwin, XPropertyEvent *event)
wwin->flags.urgent = 1;
else
wwin->flags.urgent = 0;
} else {
wwin->group_id = None;
} else if (wwin->fake_group!=NULL) {
wwin->group_id = wwin->fake_group->window;
} else {
wwin->group_id = None;
}
break;

View File

@@ -234,11 +234,19 @@ toggleLoweredCallback(WMenu *menu, WMenuEntry *entry)
}
static int
matchWindow(void *item, void *cdata)
{
return (((WFakeGroupLeader*)item)->window == (Window)cdata);
}
static void
killCallback(WMenu *menu, WMenuEntry *entry)
{
WScreen *scr = menu->menu->screen_ptr;
WAppIcon *icon;
WFakeGroupLeader *fPtr;
char *buffer;
if (!WCHECK_STATE(WSTATE_NORMAL))
@@ -257,10 +265,35 @@ killCallback(WMenu *menu, WMenuEntry *entry)
"Any unsaved changes will be lost.\n"
"Please confirm."));
if (icon->icon && icon->icon->owner) {
fPtr = icon->icon->owner->fake_group;
} else {
/* is this really necessary? can we kill a dock icon not running? */
Window win = icon->main_window;
int index;
index = WMFindInArray(scr->fakeGroupLeaders, matchWindow, (void*)win);
if (index != WANotFound)
fPtr = WMGetFromArray(scr->fakeGroupLeaders, index);
else
fPtr = NULL;
}
if (wPreferences.dont_confirm_kill
|| wMessageDialog(menu->frame->screen_ptr, _("Kill Application"),
buffer, _("Yes"), _("No"), NULL)==WAPRDefault) {
if (icon->icon && icon->icon->owner) {
if (fPtr!=NULL) {
WWindow *wwin, *twin;
wwin = scr->focused_window;
while (wwin) {
twin = wwin->prev;
if (wwin->fake_group == fPtr) {
wClientKill(wwin);
}
wwin = twin;
}
} else if (icon->icon && icon->icon->owner) {
wClientKill(icon->icon->owner);
}
}
@@ -2396,14 +2429,6 @@ wDockDetach(WDock *dock, WAppIcon *icon)
wAppIconPaint(icon);
if (wPreferences.auto_arrange_icons) {
wArrangeIcons(dock->screen_ptr, True);
} else {
WAppIcon *bla = wAppIconNextSibling(icon);
if (bla) {
SlideWindow(icon->icon->core->window, icon->x_pos, icon->y_pos,
bla->x_pos, bla->y_pos);
wAppIconMove(icon, bla->x_pos, bla->y_pos);
}
}
}
if (dock->auto_collapse || dock->auto_raise_lower)
@@ -3123,7 +3148,7 @@ wDockTrackWindowLaunch(WDock *dock, Window window)
if (XGetCommand(dpy, window, &argv, &argc)) {
if (argc > 0 && argv != NULL)
command = wtokenjoin(argv,argc);
command = wtokenjoin(argv, argc);
if (argv) {
XFreeStringList(argv);
}
@@ -3262,16 +3287,17 @@ trackDeadProcess(pid_t pid, unsigned char status, WDock *dock)
icon->pid = 0;
if (status==111) {
char msg[PATH_MAX];
char *cmd;
if (icon->drop_launch)
snprintf(msg, sizeof(msg), _("Could not execute command \"%s\""),
icon->dnd_command);
if (icon->drop_launch)
cmd = icon->dnd_command;
else if (icon->paste_launch)
snprintf(msg, sizeof(msg), _("Could not execute command \"%s\""),
icon->paste_command);
cmd = icon->paste_command;
else
snprintf(msg, sizeof(msg), _("Could not execute command \"%s\""),
icon->command);
cmd = icon->command;
snprintf(msg, sizeof(msg),
_("Could not execute command \"%s\""), cmd);
wMessageDialog(dock->screen_ptr, _("Error"), msg,
_("OK"), NULL, NULL);

View File

@@ -660,6 +660,8 @@ wScreenInit(int screen_number)
scr->totalUsableArea.x2 = scr->scr_width;
scr->totalUsableArea.y2 = scr->scr_height;
scr->fakeGroupLeaders = WMCreateArray(16);
#if 0
if (!aquireManagerSelection(scr)) {
wfree(scr);

View File

@@ -110,6 +110,8 @@ typedef struct _WScreen {
WMArray *selected_windows;
WMArray *fakeGroupLeaders; /* list of fake window group ids */
struct WAppIcon *app_icon_list; /* list of all app-icons on screen */
struct WApplication *wapp_list; /* list of all aplications */

View File

@@ -214,9 +214,6 @@
#undef GRADIENT_CLIP_ARROWS
#undef NO_WINDOW_ENUMERATOR
/*
*--------------------------------------------------------------------
* Default Configuration

View File

@@ -80,11 +80,11 @@ static WMPropList *AUnfocusable;
static WMPropList *AAlwaysUserIcon;
static WMPropList *AStartMiniaturized;
static WMPropList *AStartMaximized;
static WMPropList *AStartHidden; /* app */
static WMPropList *ADontSaveSession; /* app */
static WMPropList *AStartHidden; /* app */
static WMPropList *ADontSaveSession; /* app */
static WMPropList *AEmulateAppIcon;
static WMPropList *AFullMaximize;
static WMPropList *ACollapseAppIcons; /* app */
static WMPropList *ASharedAppIcon; /* app */
#ifdef XKB_BUTTON_HINT
static WMPropList *ANoLanguageButton;
#endif
@@ -125,7 +125,7 @@ init_wdefaults(WScreen *scr)
ADontSaveSession = WMCreatePLString("DontSaveSession");
AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
AFullMaximize = WMCreatePLString("FullMaximize");
ACollapseAppIcons = WMCreatePLString("CollapseAppIcons");
ASharedAppIcon = WMCreatePLString("SharedAppIcon");
#ifdef XKB_BUTTON_HINT
ANoLanguageButton = WMCreatePLString("NoLanguageButton");
#endif
@@ -256,13 +256,13 @@ wDefaultFillAttributes(WScreen *scr, char *instance, char *class,
/* get the data */
value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault);
APPLY_VAL(value, no_titlebar, ANoTitlebar);
value = get_value(dw, dc, dn, da, ANoResizebar, No, useGlobalDefault);
APPLY_VAL(value, no_resizebar, ANoResizebar);
value = get_value(dw, dc, dn, da, ANoMiniaturizeButton, No, useGlobalDefault);
APPLY_VAL(value, no_miniaturize_button, ANoMiniaturizeButton);
value = get_value(dw, dc, dn, da, ANoCloseButton, No, useGlobalDefault);
APPLY_VAL(value, no_close_button, ANoCloseButton);
@@ -271,19 +271,19 @@ wDefaultFillAttributes(WScreen *scr, char *instance, char *class,
value = get_value(dw, dc, dn, da, ANoHideOthers, No, useGlobalDefault);
APPLY_VAL(value, no_hide_others, ANoHideOthers);
value = get_value(dw, dc, dn, da, ANoMouseBindings, No, useGlobalDefault);
APPLY_VAL(value, no_bind_mouse, ANoMouseBindings);
value = get_value(dw, dc, dn, da, ANoKeyBindings, No, useGlobalDefault);
APPLY_VAL(value, no_bind_keys, ANoKeyBindings);
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, ASharedAppIcon, No, useGlobalDefault);
APPLY_VAL(value, shared_appicon, ASharedAppIcon);
value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault);
APPLY_VAL(value, floating, AKeepOnTop);

View File

@@ -238,23 +238,33 @@ wWindowDestroy(WWindow *wwin)
}
}
if (wwin->fake_group) {
if (wwin->fake_group->retainCount > 0)
wwin->fake_group->retainCount--;
if (wwin->fake_group->retainCount==0 && wwin->fake_group->window!=None) {
XDestroyWindow(dpy, wwin->fake_group->window);
wwin->fake_group->window = None;
XFlush(dpy);
}
}
if (wwin->normal_hints)
XFree(wwin->normal_hints);
XFree(wwin->normal_hints);
if (wwin->wm_hints)
XFree(wwin->wm_hints);
XFree(wwin->wm_hints);
if (wwin->wm_instance)
XFree(wwin->wm_instance);
XFree(wwin->wm_instance);
if (wwin->wm_class)
XFree(wwin->wm_class);
XFree(wwin->wm_class);
if (wwin->wm_gnustep_attr)
wfree(wwin->wm_gnustep_attr);
wfree(wwin->wm_gnustep_attr);
if (wwin->cmap_windows)
XFree(wwin->cmap_windows);
XFree(wwin->cmap_windows);
XDeleteContext(dpy, wwin->client_win, wWinContext);
@@ -524,6 +534,45 @@ wWindowObscuresWindow(WWindow *wwin, WWindow *obscured)
}
static Window
createFakeWindowGroupLeader(WScreen *scr, Window win, char *instance, char *class)
{
XClassHint *classHint;
XWMHints *hints;
Window leader;
int argc;
char **argv;
leader = XCreateSimpleWindow(dpy, scr->root_win, 10, 10, 10, 10, 0, 0, 0);
/* set class hint */
classHint = XAllocClassHint();
classHint->res_name = instance;
classHint->res_class = class;
XSetClassHint(dpy, leader, classHint);
XFree(classHint);
/* set window group leader to self */
hints = XAllocWMHints();
hints->window_group = leader;
hints->flags = WindowGroupHint;
XSetWMHints(dpy, leader, hints);
XFree(hints);
if (XGetCommand(dpy, win, &argv, &argc)!=0 && argc > 0) {
XSetCommand(dpy, leader, argv, argc);
XFreeStringList(argv);
}
return leader;
}
static int
matchIdentifier(void *item, void *cdata)
{
return (strcmp(((WFakeGroupLeader*)item)->identifier, (char*)cdata)==0);
}
/*
*----------------------------------------------------------------
@@ -690,7 +739,7 @@ wManageWindow(WScreen *scr, Window window)
}
PropGetProtocols(window, &wwin->protocols);
if (!XGetTransientForHint(dpy, window, &wwin->transient_for)) {
wwin->transient_for = None;
} else {
@@ -744,13 +793,53 @@ wManageWindow(WScreen *scr, Window window)
}
#endif /* OLWM_HINTS */
/*
* Make broken apps behave as a nice app.
*/
/* Make broken apps behave as a nice app. */
if (WFLAGP(wwin, emulate_appicon)) {
wwin->main_window = wwin->client_win;
}
if (!withdraw && wwin->main_window && WFLAGP(wwin, shared_appicon)) {
char *buffer, *instance, *class;
WFakeGroupLeader *fPtr;
int index;
PropGetWMClass(wwin->main_window, &class, &instance);
buffer = wmalloc(strlen(instance)+strlen(class)+2);
sprintf(buffer, "%s.%s", instance, class);
index = WMFindInArray(scr->fakeGroupLeaders, matchIdentifier, (void*)buffer);
if (index != WANotFound) {
fPtr = WMGetFromArray(scr->fakeGroupLeaders, index);
if (fPtr->retainCount == 0) {
fPtr->window = createFakeWindowGroupLeader(scr, wwin->main_window,
instance, class);
}
fPtr->retainCount++;
wwin->fake_group = fPtr;
wwin->group_id = fPtr->window;
wwin->main_window = wwin->group_id;
wfree(buffer);
} else {
fPtr = (WFakeGroupLeader*)wmalloc(sizeof(WFakeGroupLeader));
fPtr->identifier = buffer;
fPtr->window = createFakeWindowGroupLeader(scr, wwin->main_window,
instance, class);
fPtr->retainCount = 1;
WMAddToArray(scr->fakeGroupLeaders, fPtr);
wwin->fake_group = fPtr;
wwin->group_id = fPtr->window;
wwin->main_window = wwin->group_id;
}
if (instance)
XFree(instance);
if (class)
XFree(class);
}
/*
*------------------------------------------------------------
*
@@ -1099,6 +1188,8 @@ wManageWindow(WScreen *scr, Window window)
if (app) {
app->last_workspace = workspace;
app->main_window_desc->fake_group = wwin->fake_group;
/*
* Do application specific stuff, like setting application
* wide attributes.
@@ -1747,47 +1838,23 @@ wWindowUnfocus(WWindow *wwin)
void
wWindowUpdateName(WWindow *wwin, char *newTitle)
{
WApplication *app = wApplicationOf(wwin->main_window);
int instIndex = 0;
char prefix[32] = "";
char *title;
if (!wwin->frame)
return;
if (app)
instIndex = wApplicationIndexOfGroup(app);
wwin->flags.wm_name_changed = 1;
if (!newTitle) {
/* the hint was removed */
title = DEF_WINDOW_TITLE;
WMPostNotificationName(WMNChangedName, wwin, NULL);
} else {
title = newTitle;
}
#ifndef NO_WINDOW_ENUMERATOR
if (instIndex > 0) {
snprintf(prefix, sizeof(prefix), " [%i]", instIndex);
title = wstrconcat(title, prefix);
}
#endif
if (wFrameWindowChangeTitle(wwin->frame, title)) {
if (wFrameWindowChangeTitle(wwin->frame, title)) {
WMPostNotificationName(WMNChangedName, wwin, NULL);
}
#ifndef NO_WINDOW_ENUMERATOR
if (instIndex > 0)
wfree(title);
#endif
}

View File

@@ -56,7 +56,7 @@ typedef enum {
* window attribute flags.
*
* Note: attributes that should apply to the application as a
* whole should only access the flags from the app->main_window_desc->window_flags
* whole should only access the flags from app->main_window_desc->window_flags
* This is to make sure that the application doesn't have many different
* values for the same option. For example, imagine xfoo, which has
* foo.bar as leader and it a child window named foo.baz. If you set
@@ -119,7 +119,7 @@ typedef struct {
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 shared_appicon:1;
unsigned int dont_move_off:1;
@@ -166,6 +166,16 @@ typedef struct {
} WProtocols;
/*
* Structure used for storing fake window group information
*/
typedef struct WFakeGroupLeader {
char *identifier;
Window window;
int retainCount;
} WFakeGroupLeader;
/*
* Stores client window information. Each client window has it's
* structure created when it's being first mapped.
@@ -207,20 +217,23 @@ typedef struct WWindow {
GNUstepWMAttributes *wm_gnustep_attr;/* GNUstep window attributes */
int state; /* state as in ICCCM */
Window transient_for; /* WM_TRANSIENT_FOR */
WFakeGroupLeader *fake_group; /* Fake group leader for grouping into
a single appicon */
Window group_id; /* the leader window of the group */
Window client_leader; /* WM_CLIENT_LEADER if not
internal_window */
internal_window */
Window main_window; /* main window for the application */
int cmap_window_no;
Window *cmap_windows;
/* protocols */
WProtocols protocols; /* accepted WM_PROTOCOLS */
FocusMode focus_mode; /* type of keyboard input focus */
#ifdef OLWM_HINTS_unfinished

View File

@@ -154,7 +154,7 @@ static WMPropList *AStartMaximized;
static WMPropList *ADontSaveSession;
static WMPropList *AEmulateAppIcon;
static WMPropList *AFullMaximize;
static WMPropList *ACollapseAppIcons;
static WMPropList *ASharedAppIcon;
#ifdef XKB_BUTTON_HINT
static WMPropList *ANoLanguageButton;
#endif
@@ -222,7 +222,7 @@ make_keys()
ADontSaveSession = WMCreatePLString("DontSaveSession");
AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
AFullMaximize = WMCreatePLString("FullMaximize");
ACollapseAppIcons = WMCreatePLString("CollapseAppIcons");
ASharedAppIcon = WMCreatePLString("SharedAppIcon");
#ifdef XKB_BUTTON_HINT
ANoLanguageButton = WMCreatePLString("NoLanguageButton");
#endif
@@ -661,7 +661,7 @@ saveSettings(WMButton *button, InspectorPanel *panel)
different |= insertAttribute(dict, winDic, ANoAppIcon, value, flags);
value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No;
different |= insertAttribute(dict, winDic, ACollapseAppIcons, value, flags);
different |= insertAttribute(dict, winDic, ASharedAppIcon, value, flags);
}
WMRemoveFromPLDictionary(dict, key);
@@ -715,7 +715,7 @@ saveSettings(WMButton *button, InspectorPanel *panel)
flags);
value = (WMGetButtonSelected(panel->appChk[2])!=0) ? Yes : No;
different |= insertAttribute(dict, appDic, ACollapseAppIcons, value,
different |= insertAttribute(dict, appDic, ASharedAppIcon, value,
flags);
WMRemoveFromPLDictionary(dict, key);
@@ -902,7 +902,7 @@ applySettings(WMButton *button, InspectorPanel *panel)
WSETUFLAG(wapp->main_window_desc, no_appicon,
WMGetButtonSelected(panel->appChk[1]));
WSETUFLAG(wapp->main_window_desc, collapse_appicons,
WSETUFLAG(wapp->main_window_desc, shared_appicon,
WMGetButtonSelected(panel->appChk[2]));
if (WFLAGP(wapp->main_window_desc, no_appicon))
@@ -1040,7 +1040,7 @@ revertSettings(WMButton *button, InspectorPanel *panel)
flag = WFLAGP(wapp->main_window_desc, no_appicon);
break;
case 2:
flag = WFLAGP(wapp->main_window_desc, collapse_appicons);
flag = WFLAGP(wapp->main_window_desc, shared_appicon);
break;
}
WMSetButtonSelected(panel->appChk[i], flag);
@@ -1609,10 +1609,10 @@ createInspectorForWindow(WWindow *wwin, int xpos, int ypos,
"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");
caption = _("Shared application icon");
flag = WFLAGP(wapp->main_window_desc, shared_appicon);
descr = _("Use a single shared application icon for all of\n"
"the instances of this application.\n");
break;
}
panel->appChk[i] = WMCreateSwitchButton(panel->appFrm);