static int AutoraiseTimeout(void *data) { EWin *ewin = (EWin *) data; if (Conf.focus.mode == MODE_FOCUS_CLICK) goto done; if (EwinFindByPtr(ewin)) /* May be gone */ EwinRaise(ewin); done: focus_timer_autoraise = NULL; return 0; }
/* NB - this doesnt free imageclasses if we created them for the menu * FIXME: so it will leak if we create new imageclasses and stop using * old ones for menu icons. we need to add some ref counting in menu icon * imageclasses to knw to free them when not used */ void MenuEmpty(Menu * m, int destroying) { int i, j; MenuItem *mi; for (i = 0; i < m->num; i++) { mi = m->items[i]; if (mi->child) { mi->child->ref_count--; MenuDestroy(mi->child); } Efree(mi->text); Efree(mi->params); for (j = 0; j < 3; j++) PmapMaskFree(&(mi->pmm[j])); if (!destroying && mi->win) EDestroyWindow(mi->win); else EventCallbackUnregister(mi->win, MenuItemHandleEvents, mi); ImageclassFree(mi->icon_iclass); Efree(mi); } Efree(m->items); m->items = NULL; m->num = 0; m->sel_item = NULL; PmapMaskFree(&m->pmm); m->last_change = 0; m->filled = 0; } static void MenuFreePixmaps(Menu * m) { int i, j; MenuItem *mi; for (i = 0; i < m->num; i++) { mi = m->items[i]; for (j = 0; j < 3; j++) PmapMaskFree(mi->pmm + j); } PmapMaskFree(&m->pmm); m->last_change = 0; m->filled = 0; } #if 0 /* Unused */ void MenuRepack(Menu * m) { EWin *ewin; m->redraw = 1; if (m->win) MenuRealize(m); ewin = m->ewin; if (!ewin) return; ICCCM_SetSizeConstraints(ewin, m->w, m->h, m->w, m->h, 0, 0, 1, 1, 0.0, 65535.0); EwinResize(ewin, m->w, m->h, 0); EwinRaise(ewin); }
static void WarpFocusClick(int ix) { EWin *ewin; if (!warplist) return; if (ix < 0 || ix >= warplist_num) return; if (ix == warpFocusIndex) return; warpFocusIndex = ix; WarpFocusShow(); ewin = warplist[ix].ewin; if (!EwinFindByPtr(ewin)) return; if (Conf.focus.raise_on_next) EwinRaise(ewin); FocusToEWin(ewin, FOCUS_SET); }
static void doFocusToEwin(EWin * ewin, int why) { int do_focus = 0; int do_raise = 0, do_warp = 0; if (focus_inhibit) return; if (EDebug(EDBUG_TYPE_FOCUS)) Eprintf("%s: %#x %s why=%d\n", __func__, (ewin) ? EwinGetClientXwin(ewin) : 0, (ewin) ? EwinGetTitle(ewin) : "None", why); switch (why) { case FOCUS_NEXT: case FOCUS_PREV: if (Conf.focus.raise_on_next) do_raise = 1; if (Conf.focus.warp_on_next) do_warp = 1; /* Fall thru */ default: case FOCUS_SET: case FOCUS_ENTER: case FOCUS_LEAVE: /* Unused */ case FOCUS_CLICK: if (ewin && ewin == Mode.focuswin) return; if (!ewin) /* Unfocus */ break; if (!FocusEwinValid(ewin, 1, why == FOCUS_CLICK, 0)) return; break; case FOCUS_INIT: case FOCUS_DESK_ENTER: ewin = FocusEwinSelect(); break; case FOCUS_DESK_LEAVE: focus_is_set = 0; /* FALLTHROUGH */ case FOCUS_NONE: ewin = NULL; if (ewin == Mode.focuswin) return; break; case FOCUS_EWIN_UNMAP: if (Mode.focuswin) return; ewin = FocusEwinSelect(); if (ewin == Mode.focuswin) ewin = NULL; break; case FOCUS_EWIN_NEW: if (Conf.focus.all_new_windows_get_focus) goto check_focus_new; if (Mode.place.doing_manual) goto check_focus_new; if (ewin->props.focus_when_mapped) goto check_focus_new; if (Conf.focus.new_windows_get_focus_if_group_focused && Mode.focuswin) { if (EwinGetWindowGroup(ewin) == EwinGetWindowGroup(Mode.focuswin)) goto check_focus_new; } if (EwinIsTransient(ewin)) { if (Conf.focus.new_transients_get_focus) { do_focus = 1; } else if (Conf.focus.new_transients_get_focus_if_group_focused && Mode.focuswin) { if ((EwinGetTransientFor(ewin) == EwinGetClientXwin(Mode.focuswin)) || (EwinGetWindowGroup(ewin) == EwinGetWindowGroup(Mode.focuswin))) do_focus = 1; } if (!do_focus) return; DeskGotoByEwin(ewin); goto check_focus_new; } return; check_focus_new: if (!FocusEwinValid(ewin, 1, 0, 0)) return; break; } if (ewin == Mode.focuswin && focus_is_set) return; /* Check if ewin is a valid focus window target */ if (!ewin) goto done; /* NB! ewin != NULL */ if (why != FOCUS_CLICK && ewin->props.focusclick) return; if (Conf.autoraise.enable) { TIMER_DEL(focus_timer_autoraise); if (Conf.focus.mode != MODE_FOCUS_CLICK) TIMER_ADD(focus_timer_autoraise, Conf.autoraise.delay, AutoraiseTimeout, ewin); } if (do_raise) EwinRaise(ewin); if (Conf.focus.warp_always) do_warp = 1; if (do_warp) EwinWarpTo(ewin, 0); switch (why) { case FOCUS_PREV: case FOCUS_NEXT: GrabKeyboardSet(VROOT); /* Causes idler to be called on KeyRelease */ focus_pending_raise = ewin; break; case FOCUS_DESK_ENTER: if (Conf.focus.mode == MODE_FOCUS_CLICK) break; /* FALLTHROUGH */ default: case FOCUS_INIT: EwinListFocusRaise(ewin); break; } SoundPlay(SOUND_FOCUS_SET); done: ClickGrabsUpdate(); /* Unset old focus window (if any) highlighting */ if (Mode.focuswin) FocusEwinSetActive(Mode.focuswin, 0); ICCCM_Cmap(ewin); /* Quit if pointer is not on our screen */ if (!Mode.events.on_screen) { Mode.focuswin = NULL; return; } /* Set new focus window (if any) highlighting */ Mode.focuswin = ewin; if (Mode.focuswin) FocusEwinSetActive(Mode.focuswin, 1); if (why == FOCUS_DESK_LEAVE) return; ICCCM_Focus(ewin); focus_is_set = 1; }
void WarpFocus(int delta) { WarpFocusWin *fw = warpFocusWindow; EWin *const *lst; EWin *ewin; int i, num; WarplistItem *wl; /* Remember invoking keycode (ugly hack) */ if (!fw || !EoIsShown(fw)) { warpFocusKey = Mode.events.last_keycode; warpFocusState = Mode.events.last_keystate; } if (!warplist) { warplist_num = 0; /* Not necessary but silences clang */ lst = EwinListFocusGet(&num); for (i = 0; i < num; i++) { ewin = lst[i]; if ( /* Either visible or iconified */ ((EwinIsOnScreen(ewin)) || (ewin->state.iconified) || (Conf.warplist.showalldesks)) && /* Exclude windows that explicitely say so */ (!ewin->props.skip_focuslist) && (!ewin->props.skip_ext_task) && /* Keep shaded windows if conf say so */ ((!ewin->state.shaded) || (Conf.warplist.showshaded)) && /* Keep sticky windows if conf say so */ ((!EoIsSticky(ewin)) || (Conf.warplist.showsticky)) && /* Keep iconified windows if conf say so */ ((!ewin->state.iconified) || (Conf.warplist.showiconified))) { warplist_num++; warplist = EREALLOC(WarplistItem, warplist, warplist_num); wl = warplist + warplist_num - 1; wl->ewin = ewin; } } /* Hmmm. Hack... */ if (warplist_num >= 2 && warplist[1].ewin == GetFocusEwin()) { warplist[1].ewin = warplist[0].ewin; warplist[0].ewin = GetFocusEwin(); } warpFocusIndex = 0; } if (!warplist) return; warpFocusIndex = (warpFocusIndex + warplist_num + delta) % warplist_num; ewin = warplist[warpFocusIndex].ewin; if (!EwinFindByPtr(ewin)) ewin = NULL; if (!ewin) return; WarpFocusShow(); if (!EwinIsOnScreen(ewin)) return; if (Conf.warplist.show_shape) WarpShapeDraw(ewin); if (Conf.focus.raise_on_next) EwinRaise(ewin); if (Conf.focus.warp_on_next) EwinWarpTo(ewin, 0); if (Conf.warplist.warpfocused) FocusToEWin(ewin, FOCUS_SET); }
static void MenuShow(Menu * m, char noshow) { EWin *ewin; int x, y, w, h; int wx, wy, mw, mh; int head_num = 0; if (m->shown) return; if (MenuLoad(m) || m->redraw) MenuRealize(m); if (m->num <= 0) return; if (!m->win || !m->items[0]->win) MenuRealize(m); if (!m->style) return; ewin = m->ewin; if (ewin) { #if 0 /* ??? */ EwinRaise(ewin); EwinShow(ewin); return; #else MenuHide(m); #endif } EGetGeometry(m->items[0]->win, NULL, &x, &y, &w, &h, NULL, NULL); mw = m->w; mh = m->h; EQueryPointer(NULL, &wx, &wy, NULL, NULL); wx -= EoGetX(DesksGetCurrent()) + x + (w / 2); wy -= EoGetY(DesksGetCurrent()) + y + (h / 2); if (Conf.menus.onscreen) { Border *b; b = BorderFind(m->style->border_name); if (b) { int sx, sy, sw, sh; head_num = ScreenGetGeometryByPointer(&sx, &sy, &sw, &sh); if (wx > sx + sw - mw - b->border.right) wx = sx + sw - mw - b->border.right; if (wx < sx + b->border.left) wx = sx + b->border.left; if (wy > sy + sh - mh - b->border.bottom) wy = sy + sh - mh - b->border.bottom; if (wy < sy + b->border.top) wy = sy + b->border.top; } } EMoveWindow(m->win, wx, wy); ewin = AddInternalToFamily(m->win, m->style->border_name, EWIN_TYPE_MENU, &_MenuEwinOps, m); if (ewin) { ewin->client.event_mask |= KeyPressMask; ESelectInput(m->win, ewin->client.event_mask); ewin->head = head_num; EwinResize(ewin, ewin->client.w, ewin->client.h, 0); if (Conf.menus.animate) EwinInstantShade(ewin, 0); if (!noshow) { ICCCM_Cmap(NULL); EwinOpFloatAt(ewin, OPSRC_NA, EoGetX(ewin), EoGetY(ewin)); EwinShow(ewin); if (Conf.menus.animate) EwinUnShade(ewin); } } m->shown = 1; m->last_access = time(0); Mode_menus.just_shown = 1; if (!Mode_menus.first) { Mode_menus.context_ewin = GetContextEwin(); #if 0 Eprintf("Mode_menus.context_ewin set %s\n", EwinGetTitle(Mode_menus.context_ewin)); #endif ESync(ESYNC_MENUS); Mode_menus.first = m; MenuShowMasker(m); TooltipsEnable(0); GrabKeyboardSet(m->win); } m->ref_count++; }
/* outstanding BUG: zooming on shaped windows leaves stuff exposed beneath them..... */ void Zoom(EWin * ewin, int on) { if (Mode.wm.window) return; if (!ewin) ewin = zoom_last_ewin; if (!ewin) return; if (zoom_can == 0) ZoomInit(); if (zoom_can <= 0) return; Dprintf("%s: on=%d\n", __func__, on); if (!on) { /* Unzoom */ if (ewin != zoom_last_ewin) return; _ZoomEwinRestore(ewin); SwitchRes(0, 0, 0, 0, 0, NULL, NULL); zw = zh = 0; zoom_last_ewin = NULL; } else if (ewin == zoom_last_ewin) { /* Already zoomed */ return; } else { /* Zoom */ if (ewin->state.fullscreen) return; if (!zoom_last_ewin) /* first zoom */ { on = SwitchRes(1, 0, 0, ewin->client.w, ewin->client.h, &zw, &zh); } else /* we are zoomed in on another window already.... */ { _ZoomEwinRestore(zoom_last_ewin); if ((ewin->client.w <= zw) && (ewin->client.h <= zh) && ((ewin->client.w >= zw / 2) || (ewin->client.h >= zh / 2))) { /* YAY no need to change resolution :-D */ } else { /* SwitchRes only tracks the LAST mode, so we have to switch back to * the original mode before switching to new target mode * so that we can restore the original vid mode when we zoom * out of the last window ;( */ SwitchRes(0, 0, 0, 0, 0, NULL, NULL); on = SwitchRes(1, 0, 0, ewin->client.w, ewin->client.h, &zw, &zh); } } Dprintf("%s: SwitchRes=%d - client size %dx%d -> screen %dx%d\n", __func__, on, ewin->client.w, ewin->client.h, zw, zh); if (!on) return; ewin->save_fs.x = EoGetX(ewin); ewin->save_fs.y = EoGetY(ewin); EwinRaise(ewin); EwinBorderSetTo(ewin, BorderCreateFiller(ewin->client.w, ewin->client.h, zw, zh)); EwinMoveResize(ewin, 0, 0, ewin->client.w, ewin->client.h, 0); ewin->state.zoomed = 1; FocusToEWin(ewin, FOCUS_SET); zoom_last_ewin = ewin; } EwinWarpTo(ewin, 1); ESync(0); EwinStateUpdate(ewin); HintsSetWindowState(ewin); }