From de1c885ef6152c922914a362a6e2cb38a6737841 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Wed, 21 Apr 2004 20:51:57 +0000 Subject: [PATCH] Another attempt at fixing the "losing windows" bug, adjust event masks. SVN revision: 9831 --- src/E.h | 10 ++- src/borders.c | 87 ++++++++++---------- src/desktops.c | 2 +- src/evhandlers.c | 4 +- src/focus.c | 2 +- src/icccm.c | 8 -- src/iconify.c | 209 +++++++++++++++++++++++------------------------ src/main.c | 10 ++- src/menus.c | 2 + 9 files changed, 171 insertions(+), 163 deletions(-) diff --git a/src/E.h b/src/E.h index ddd0521c..7c443028 100644 --- a/src/E.h +++ b/src/E.h @@ -881,6 +881,11 @@ typedef struct _winclient } WinClient; +#define EWIN_STATE_UNKNOWN 0 +#define EWIN_STATE_WITHDRAWN 1 +#define EWIN_STATE_ICONIC 2 +#define EWIN_STATE_MAPPED 3 + #define EWIN_TYPE_NORMAL 0x00 #define EWIN_TYPE_DIALOG 0x01 #define EWIN_TYPE_MENU 0x02 @@ -893,6 +898,7 @@ struct _ewin int x, y, w, h, reqx, reqy; int lx, ly, lw, lh; char type; + char state; char internal; char toggle; Window win_container; @@ -904,7 +910,6 @@ struct _ewin int desktop; Group **groups; int num_groups; - char mapped; char docked; char sticky; char visible; @@ -1723,8 +1728,8 @@ void AddToFamily(Window win); EWin *AddInternalToFamily(Window win, const char *bname, int type, void *ptr, void (*init) (EWin * ewin, void *ptr)); -void CalcEwinSizes(EWin * ewin); void HonorIclass(char *s, int id); +void EwinWithdraw(EWin * ewin); void SyncBorderToEwin(EWin * ewin); void UpdateBorderInfo(EWin * ewin); void RealiseEwinWinpart(EWin * ewin, int i); @@ -2283,7 +2288,6 @@ void IclassApplyCopy(ImageClass * iclass, Window win, int w, void FreePmapMask(PmapMask * pmm); /* iconify.c */ -void IB_Animate(char iconify, EWin * from, EWin * to); void IconifyEwin(EWin * ewin); void DeIconifyEwin(EWin * ewin); void MakeIcon(EWin * ewin); diff --git a/src/borders.c b/src/borders.c index fe22721d..bd3d1efb 100644 --- a/src/borders.c +++ b/src/borders.c @@ -25,11 +25,11 @@ #define EWIN_TOP_EVENT_MASK \ (ButtonPressMask | ButtonReleaseMask | \ - EnterWindowMask | LeaveWindowMask | PointerMotionMask | \ - StructureNotifyMask) + EnterWindowMask | LeaveWindowMask | PointerMotionMask /* | \ + StructureNotifyMask */) #define EWIN_CONTAINER_EVENT_MASK \ - (ButtonPressMask | ButtonReleaseMask | \ - StructureNotifyMask | ResizeRedirectMask | \ + (/* ButtonPressMask | ButtonReleaseMask | */ \ + /* StructureNotifyMask | ResizeRedirectMask | */ \ SubstructureNotifyMask | SubstructureRedirectMask) #define EWIN_BORDER_PART_EVENT_MASK \ (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ @@ -39,7 +39,7 @@ #define EWIN_CLIENT_EVENT_MASK \ (EnterWindowMask | LeaveWindowMask | FocusChangeMask | \ - StructureNotifyMask | ResizeRedirectMask | \ + /* StructureNotifyMask | */ ResizeRedirectMask | \ PropertyChangeMask | ColormapChangeMask) static void EwinSetBorderInit(EWin * ewin); @@ -142,7 +142,7 @@ GetEwinPointerInClient(void) { Window rt, ch; int dum, px, py, d; - EWin *const *lst; + EWin *const *lst, *ewin; int i, num; EDBUG(5, "GetEwinPointerInClient"); @@ -158,13 +158,14 @@ GetEwinPointerInClient(void) { int x, y, w, h; - x = lst[i]->x; - y = lst[i]->y; - w = lst[i]->w; - h = lst[i]->h; - if ((px >= x) && (py >= y) && (px < (x + w)) && (py < (y + h)) - && (lst[i]->visible)) - EDBUG_RETURN(lst[i]); + ewin = lst[i]; + x = ewin->x; + y = ewin->y; + w = ewin->w; + h = ewin->h; + if ((px >= x) && (py >= y) && (px < (x + w)) && (py < (y + h)) && + (ewin->visible) && (ewin->state == EWIN_STATE_MAPPED)) + EDBUG_RETURN(ewin); } EDBUG_RETURN(NULL); @@ -348,8 +349,10 @@ AddToFamily(Window win) char cangrab = 0; EDBUG(3, "AddToFamily"); + /* find the client window if it's already managed */ ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + /* it's already managed */ if (ewin) { @@ -364,6 +367,7 @@ AddToFamily(Window win) ConformEwinToDesktop(ewin); ShowEwin(ewin); ICCCM_DeIconify(ewin); + ewin->iconified = 0; } EDBUG_RETURN_; } @@ -385,13 +389,7 @@ AddToFamily(Window win) /* if set for borderless then dont slide it in */ if ((!ewin->client.mwm_decor_title) && (!ewin->client.mwm_decor_border)) doslide = 0; - if (!Mode.startup) - { - if (ewin->client.start_iconified) - ewin->iconified = 1; - } - x = 0; - y = 0; + ResizeEwin(ewin, ewin->client.w, ewin->client.h); if (ewin->client.transient) @@ -460,6 +458,8 @@ AddToFamily(Window win) } /* if it hasn't been placed yet.... find a spot for it */ + x = 0; + y = 0; if ((!ewin->client.already_placed) && (!manplace)) { @@ -558,14 +558,11 @@ AddToFamily(Window win) } /* if the window asked to be iconified at the start */ - if (ewin->iconified) + if (ewin->client.start_iconified) { EwinBorderDraw(ewin, 1, 1); MoveEwinToDesktopAt(ewin, ewin->desktop, x, y); - RaiseEwin(ewin); - ShowEwin(ewin); UngrabX(); - ewin->iconified = 0; IconifyEwin(ewin); EDBUG_RETURN_; } @@ -1023,7 +1020,7 @@ CalcEwinWinpart(EWin * ewin, int i) EDBUG_RETURN_; } -void +static void CalcEwinSizes(EWin * ewin) { int i; @@ -1314,6 +1311,7 @@ EwinDestroy(EWin * ewin) if (!ewin) EDBUG_RETURN_; + RemoveItem(NULL, ewin->client.win, LIST_FINDBY_ID, LIST_TYPE_EWIN); EwinListDelete(&EwinListStack, ewin); EwinListDelete(&EwinListFocus, ewin); @@ -1371,6 +1369,23 @@ EwinDestroy(EWin * ewin) EDBUG_RETURN_; } +void +EwinWithdraw(EWin * ewin) +{ + Window win; + + /* Park the client window on the root */ + XTranslateCoordinates(disp, ewin->client.win, root.win, + -ewin->border->border.left, + -ewin->border->border.top, &ewin->client.x, + &ewin->client.y, &win); + EReparentWindow(disp, ewin->client.win, root.win, ewin->client.x, + ewin->client.y); + + ICCCM_Withdraw(ewin); + EwinDestroy(ewin); +} + void EwinEventDestroy(EWin * ewin) { @@ -1380,19 +1395,18 @@ EwinEventDestroy(EWin * ewin) void EwinEventMap(EWin * ewin) { - ewin->mapped = 1; + ewin->state = EWIN_STATE_MAPPED; } void EwinEventUnmap(EWin * ewin) { - Window win; - - ewin->mapped = 0; - if (GetZoomEWin() == ewin) Zoom(NULL); + /* Set state to unknown until we can set the correct one */ + ewin->state = (ewin->iconified) ? EWIN_STATE_ICONIC : EWIN_STATE_WITHDRAWN; + ActionsEnd(ewin); if (ewin->pager) @@ -1430,16 +1444,7 @@ EwinEventUnmap(EWin * ewin) if (ewin->Close) ewin->Close(ewin); - /* Park the client window on the root */ - XTranslateCoordinates(disp, ewin->client.win, root.win, - -ewin->border->border.left, - -ewin->border->border.top, &ewin->client.x, - &ewin->client.y, &win); - EReparentWindow(disp, ewin->client.win, root.win, ewin->client.x, - ewin->client.y); - ICCCM_Withdraw(ewin); - RemoveItem(NULL, ewin->client.win, LIST_FINDBY_ID, LIST_TYPE_EWIN); - EwinDestroy(ewin); + EwinWithdraw(ewin); } static void @@ -2065,7 +2070,7 @@ HideEwin(EWin * ewin) { EDBUG(3, "HideEwin"); - if (!ewin->mapped || !ewin->visible) + if (ewin->state != EWIN_STATE_MAPPED || !ewin->visible) EDBUG_RETURN_; ewin->visible = 0; diff --git a/src/desktops.c b/src/desktops.c index d348b538..3802a391 100644 --- a/src/desktops.c +++ b/src/desktops.c @@ -28,7 +28,7 @@ #define EDESK_EVENT_MASK \ (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | \ - SubstructureNotifyMask | SubstructureRedirectMask | PropertyChangeMask) + /* SubstructureNotifyMask | */ SubstructureRedirectMask | PropertyChangeMask) void ChangeNumberOfDesktops(int quantity) diff --git a/src/evhandlers.c b/src/evhandlers.c index 6ade9be9..0b9d608c 100644 --- a/src/evhandlers.c +++ b/src/evhandlers.c @@ -663,7 +663,7 @@ HandleDestroy(XEvent * ev) EForgetWindow(disp, win); - ewin = RemoveItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); + ewin = FindItem(NULL, win, LIST_FINDBY_ID, LIST_TYPE_EWIN); if (ewin) { EwinEventDestroy(ewin); @@ -698,7 +698,7 @@ HandleUnmap(XEvent * ev) void HandleMap(XEvent * ev) { - Window win = ev->xunmap.window; + Window win = ev->xmap.window; EWin *ewin; EDBUG(5, "HandleMap"); diff --git a/src/focus.c b/src/focus.c index 52d2ed41..ee98844b 100644 --- a/src/focus.c +++ b/src/focus.c @@ -33,7 +33,7 @@ FocusEwinValid(EWin * ewin) if (ewin->skipfocus || ewin->neverfocus || ewin->shaded || ewin->iconified) return 0; - if (!ewin->mapped) + if (ewin->state != EWIN_STATE_MAPPED) return 0; return EwinIsOnScreen(ewin); diff --git a/src/icccm.c b/src/icccm.c index 3fe71f9e..b63d1215 100644 --- a/src/icccm.c +++ b/src/icccm.c @@ -225,12 +225,8 @@ ICCCM_Iconify(EWin * ewin) EDBUG(6, "ICCCM_Iconify"); - if (!ewin) - EDBUG_RETURN_; - XChangeProperty(disp, ewin->client.win, E_XA_WM_STATE, E_XA_WM_STATE, 32, PropModeReplace, (unsigned char *)c, 2); - ewin->iconified = 3; AddItem(ewin, "ICON", ewin->client.win, LIST_TYPE_ICONIFIEDS); EUnmapWindow(disp, ewin->client.win); @@ -244,10 +240,6 @@ ICCCM_DeIconify(EWin * ewin) EDBUG(6, "ICCCM_DeIconify"); - if (!ewin) - EDBUG_RETURN_; - - ewin->iconified = 0; XChangeProperty(disp, ewin->client.win, E_XA_WM_STATE, E_XA_WM_STATE, 32, PropModeReplace, (unsigned char *)c, 2); RemoveItem("ICON", ewin->client.win, LIST_FINDBY_BOTH, LIST_TYPE_ICONIFIEDS); diff --git a/src/iconify.c b/src/iconify.c index 376364d0..54a56e15 100644 --- a/src/iconify.c +++ b/src/iconify.c @@ -31,7 +31,7 @@ static void IconboxRedraw(Iconbox * ib); #define IB_ANIM_TIME 0.25 -void +static void IB_Animate(char iconify, EWin * from, EWin * to) { double t1, t2, t, i, spd, ii; @@ -204,7 +204,7 @@ IconboxIconifyEwin(Iconbox * ib, EWin * ewin) static int call_depth = 0; char was_shaded; - EDBUG(6, "IconifyEwin"); + EDBUG(6, "IconboxIconifyEwin"); if (!ewin) EDBUG_RETURN_; if (GetZoomEWin() == ewin) @@ -212,56 +212,58 @@ IconboxIconifyEwin(Iconbox * ib, EWin * ewin) if (ewin->ibox) EDBUG_RETURN_; + if (ewin->state == EWIN_STATE_ICONIC) + EDBUG_RETURN_; + if (call_depth > 256) EDBUG_RETURN_; call_depth++; - if (!ewin->iconified) + was_shaded = ewin->shaded; + SoundPlay("SOUND_ICONIFY"); + + if (ib) { - was_shaded = ewin->shaded; - SoundPlay("SOUND_ICONIFY"); + if (ib->animate) + IB_Animate(1, ewin, ib->ewin); + UpdateAppIcon(ewin, ib->icon_mode); + IconboxAddEwin(ib, ewin); + } - if (ib) + HideEwin(ewin); + + if (was_shaded != ewin->shaded) + InstantShadeEwin(ewin, 0); + + ewin->iconified = 3; + ICCCM_Iconify(ewin); + + if (ewin->has_transients) + { + EWin **lst; + int i, num; + + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) { - if (ib->animate) - IB_Animate(1, ewin, ib->ewin); - UpdateAppIcon(ewin, ib->icon_mode); - IconboxAddEwin(ib, ewin); - } - - HideEwin(ewin); - - if (was_shaded != ewin->shaded) - InstantShadeEwin(ewin, 0); - - ICCCM_Iconify(ewin); - - if (ewin->has_transients) - { - EWin **lst; - int i, num; - - lst = ListTransientsFor(ewin->client.win, &num); - if (lst) + for (i = 0; i < num; i++) { - for (i = 0; i < num; i++) + if (!lst[i]->iconified) { - if (!lst[i]->iconified) - { - HideEwin(lst[i]); - lst[i]->iconified = 4; - } + HideEwin(lst[i]); + lst[i]->iconified = 4; } -#if ENABLE_GNOME - HintsSetClientList(); -#endif - Efree(lst); } +#if ENABLE_GNOME + HintsSetClientList(); +#endif + Efree(lst); } } - call_depth--; HintsSetWindowState(ewin); + + call_depth--; EDBUG_RETURN_; } @@ -279,80 +281,82 @@ DeIconifyEwin(EWin * ewin) int x, y, dx, dy; EDBUG(6, "DeIconifyEwin"); - call_depth++; + if (call_depth > 256) + EDBUG_RETURN_; + call_depth++; + + if (ewin->state != EWIN_STATE_ICONIC && ewin->state != EWIN_STATE_UNKNOWN) + EDBUG_RETURN_; + + RemoveMiniIcon(ewin); + + dx = ewin->w / 2; + dy = ewin->h / 2; + x = (ewin->x + dx) % root.w; + if (x < 0) + x += root.w; + x -= dx; + y = (ewin->y + dy) % root.h; + if (y < 0) + y += root.h; + y -= dy; + + dx = x - ewin->x; + dy = y - ewin->y; + + if (!ewin->sticky) + MoveEwinToDesktopAt(ewin, desks.current, ewin->x + dx, ewin->y + dy); + else + MoveEwin(ewin, ewin->x + dx, ewin->y + dy); + + SoundPlay("SOUND_DEICONIFY"); + ewin->iconified = 0; + ib = SelectIconboxForEwin(ewin); + if (ib) { - call_depth--; - return; + if (ib->animate) + IB_Animate(0, ewin, ib->ewin); } - if (ewin->iconified) + RaiseEwin(ewin); + ShowEwin(ewin); + ICCCM_DeIconify(ewin); + FocusToEWin(ewin, FOCUS_SET); + + if (ewin->has_transients) { - ib = SelectIconboxForEwin(ewin); - RemoveMiniIcon(ewin); + EWin **lst, *e; + int i, num; - dx = ewin->w / 2; - dy = ewin->h / 2; - x = (ewin->x + dx) % root.w; - if (x < 0) - x += root.w; - x -= dx; - y = (ewin->y + dy) % root.h; - if (y < 0) - y += root.h; - y -= dy; - - dx = x - ewin->x; - dy = y - ewin->y; - - if (!ewin->sticky) - MoveEwinToDesktopAt(ewin, desks.current, ewin->x + dx, ewin->y + dy); - else - MoveEwin(ewin, ewin->x + dx, ewin->y + dy); - - SoundPlay("SOUND_DEICONIFY"); - if (ib) + lst = ListTransientsFor(ewin->client.win, &num); + if (lst) { - if (ib->animate) - IB_Animate(0, ewin, ib->ewin); - } - RaiseEwin(ewin); - ShowEwin(ewin); - ICCCM_DeIconify(ewin); - FocusToEWin(ewin, FOCUS_SET); - if (ewin->has_transients) - { - EWin **lst, *e; - int i, num; - - lst = ListTransientsFor(ewin->client.win, &num); - if (lst) + for (i = 0; i < num; i++) { - for (i = 0; i < num; i++) - { - e = lst[i]; + e = lst[i]; - if (e->iconified != 4) - continue; + if (e->iconified != 4) + continue; - if (!e->sticky) - MoveEwinToDesktopAt(e, desks.current, - e->x + dx, e->y + dy); - else - MoveEwin(e, e->x + dx, e->y + dy); - RaiseEwin(e); - ShowEwin(e); - e->iconified = 0; - } -#if ENABLE_GNOME - HintsSetClientList(); -#endif - Efree(lst); + if (!e->sticky) + MoveEwinToDesktopAt(e, desks.current, + e->x + dx, e->y + dy); + else + MoveEwin(e, e->x + dx, e->y + dy); + RaiseEwin(e); + ShowEwin(e); + e->iconified = 0; } +#if ENABLE_GNOME + HintsSetClientList(); +#endif + Efree(lst); } } - call_depth--; HintsSetWindowState(ewin); + + call_depth--; EDBUG_RETURN_; } @@ -1279,7 +1283,7 @@ UpdateAppIcon(EWin * ewin, int imode) } break; case 2: - /* try E first, then snap */ + /* try E first, then snap, then app */ if (!ewin->icon_pmm.pmap) IB_GetEIcon(ewin); if (!ewin->icon_pmm.pmap) @@ -1289,6 +1293,8 @@ UpdateAppIcon(EWin * ewin, int imode) RaiseEwin(ewin); IB_SnapEWin(ewin); } + if (!ewin->icon_pmm.pmap) + IB_GetAppIcon(ewin); break; default: break; @@ -2260,7 +2266,6 @@ IB_CompleteRedraw(Iconbox * ib) void IB_Setup(void) { - EWin *const *lst; int i, num; Iconbox **ibl; @@ -2272,12 +2277,6 @@ IB_Setup(void) IconboxShow(ibl[i]); Efree(ibl); } - lst = EwinListGetAll(&num); - for (i = 0; i < num; i++) - { - if (lst[i]->client.start_iconified) - IconifyEwin(lst[i]); - } } void diff --git a/src/main.c b/src/main.c index d83d0554..a9438f6a 100644 --- a/src/main.c +++ b/src/main.c @@ -251,8 +251,10 @@ main(int argc, char **argv) SoundPlay("SOUND_STARTUP"); SoundFree("SOUND_STARTUP"); } + /* toss down the dragbar and related */ InitDesktopControls(); + /* then draw all the buttons that belong on the desktop */ ShowDesktopButtons(); @@ -260,16 +262,18 @@ main(int argc, char **argv) SessionInit(); ShowDesktopControls(); CheckEvent(); + /* retreive stuff from last time we were loaded if we're restarting */ ICCCM_GetMainEInfo(); SetupEnv(); if (Conf.mapslide) CreateStartupDisplay(0); - MapUnmap(1); + /* set some more hints */ HintsSetDesktopViewport(); desks.current = 0; - /* Set up the internal pagers */ + + /* Set up the iconboxes and pagers */ IB_Setup(); if (Conf.pagers.enable) { @@ -279,6 +283,8 @@ main(int argc, char **argv) Mode.queue_up = DRAW_QUEUE_ENABLE; } + MapUnmap(1); + /* Kill the E process owning the "init window" */ if (Mode.wm.master && init_win_ext) { diff --git a/src/menus.c b/src/menus.c index 202ad7eb..880d5f3a 100644 --- a/src/menus.c +++ b/src/menus.c @@ -131,6 +131,8 @@ MenuHide(Menu * m) m->stuck = 0; m->shown = 0; + EwinWithdraw(ewin); + EDBUG_RETURN_; }