static void updateOptionsMenu(WMenu * menu, WWindow * wwin) { WMenu *smenu = menu->cascades[menu->entries[MC_OPTIONS]->cascade]; /* keep on top check */ smenu->entries[WO_KEEP_ON_TOP]->clientdata = wwin; smenu->entries[WO_KEEP_ON_TOP]->flags.indicator_on = (wwin->frame->core->stacking->window_level == WMFloatingLevel) ? 1 : 0; wMenuSetEnabled(smenu, WO_KEEP_ON_TOP, !wwin->flags.miniaturized); smenu->entries[WO_KEEP_ON_TOP]->rtext = GetShortcutKey(wKeyBindings[WKBD_KEEP_ON_TOP]); /* keep at bottom check */ smenu->entries[WO_KEEP_AT_BOTTOM]->clientdata = wwin; smenu->entries[WO_KEEP_AT_BOTTOM]->flags.indicator_on = (wwin->frame->core->stacking->window_level == WMSunkenLevel) ? 1 : 0; wMenuSetEnabled(smenu, WO_KEEP_AT_BOTTOM, !wwin->flags.miniaturized); smenu->entries[WO_KEEP_AT_BOTTOM]->rtext = GetShortcutKey(wKeyBindings[WKBD_KEEP_AT_BOTTOM]); /* omnipresent check */ smenu->entries[WO_OMNIPRESENT]->clientdata = wwin; smenu->entries[WO_OMNIPRESENT]->flags.indicator_on = IS_OMNIPRESENT(wwin); smenu->entries[WO_OMNIPRESENT]->rtext = GetShortcutKey(wKeyBindings[WKBD_OMNIPRESENT]); smenu->flags.realized = 0; wMenuRealize(smenu); }
static void updateMenuForWindow(WMenu * menu, WWindow * wwin) { WApplication *wapp = wApplicationOf(wwin->main_window); WScreen *scr = wwin->screen_ptr; int i; updateOptionsMenu(menu, wwin); updateMaximizeMenu(menu, wwin); updateMakeShortcutMenu(menu, wwin); wMenuSetEnabled(menu, MC_HIDE, wapp != NULL && !WFLAGP(wapp->main_window_desc, no_appicon)); wMenuSetEnabled(menu, MC_CLOSE, (wwin->protocols.DELETE_WINDOW && !WFLAGP(wwin, no_closable))); if (wwin->flags.miniaturized) { static char *text = NULL; if (!text) text = _("Deminiaturize"); menu->entries[MC_MINIATURIZE]->text = text; } else { static char *text = NULL; if (!text) text = _("Miniaturize"); menu->entries[MC_MINIATURIZE]->text = text; } wMenuSetEnabled(menu, MC_MINIATURIZE, !WFLAGP(wwin, no_miniaturizable)); if (wwin->flags.maximized) { static char *text = NULL; if (!text) text = _("Unmaximize"); menu->entries[MC_MAXIMIZE]->text = text; updateUnmaximizeShortcut(menu->entries[MC_MAXIMIZE], wwin->flags.maximized); } else { static char *text = NULL; if (!text) text = _("Maximize"); menu->entries[MC_MAXIMIZE]->text = text; menu->entries[MC_MAXIMIZE]->rtext = GetShortcutKey(wKeyBindings[WKBD_MAXIMIZE]); } wMenuSetEnabled(menu, MC_MAXIMIZE, IS_RESIZABLE(wwin)); wMenuSetEnabled(menu, MC_MOVERESIZE, IS_RESIZABLE(wwin) && !wwin->flags.miniaturized); if (wwin->flags.shaded) { static char *text = NULL; if (!text) text = _("Unshade"); menu->entries[MC_SHADE]->text = text; } else { static char *text = NULL; if (!text) text = _("Shade"); menu->entries[MC_SHADE]->text = text; } wMenuSetEnabled(menu, MC_SHADE, !WFLAGP(wwin, no_shadeable) && !wwin->flags.miniaturized); if (wwin->flags.selected) { static char *text = NULL; if (!text) text = _("Deselect"); menu->entries[MC_SELECT]->text = text; } else { static char *text = NULL; if (!text) text = _("Select"); menu->entries[MC_SELECT]->text = text; } wMenuSetEnabled(menu, MC_CHANGEWKSPC, !IS_OMNIPRESENT(wwin)); if (!wwin->flags.inspector_open) { wMenuSetEnabled(menu, MC_PROPERTIES, True); } else { wMenuSetEnabled(menu, MC_PROPERTIES, False); } /* Update shortcut labels except for (Un)Maximize which is * handled separately. */ menu->entries[MC_MINIATURIZE]->rtext = GetShortcutKey(wKeyBindings[WKBD_MINIATURIZE]); menu->entries[MC_SHADE]->rtext = GetShortcutKey(wKeyBindings[WKBD_SHADE]); menu->entries[MC_HIDE]->rtext = GetShortcutKey(wKeyBindings[WKBD_HIDE]); menu->entries[MC_MOVERESIZE]->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVERESIZE]); menu->entries[MC_SELECT]->rtext = GetShortcutKey(wKeyBindings[WKBD_SELECT]); menu->entries[MC_RELAUNCH]->rtext = GetShortcutKey(wKeyBindings[WKBD_RELAUNCH]); menu->entries[MC_CLOSE]->rtext = GetShortcutKey(wKeyBindings[WKBD_CLOSE]); /* set the client data of the entries to the window */ for (i = 0; i < menu->entry_no; i++) { menu->entries[i]->clientdata = wwin; } for (i = 0; i < scr->workspace_submenu->entry_no; i++) { scr->workspace_submenu->entries[i]->clientdata = wwin; if (i == scr->current_workspace) wMenuSetEnabled(scr->workspace_submenu, i, False); else wMenuSetEnabled(scr->workspace_submenu, i, True); } menu->flags.realized = 0; wMenuRealize(menu); }
void wWorkspaceForceChange(WScreen * scr, int workspace) { WWindow *tmp, *foc = NULL, *foc2 = NULL; WWindow **toUnmap; int toUnmapSize, toUnmapCount; if (workspace >= MAX_WORKSPACES || workspace < 0) return; SendHelperMessage(scr, 'C', workspace + 1, NULL); if (workspace > w_global.workspace.count - 1) wWorkspaceMake(scr, workspace - w_global.workspace.count + 1); wClipUpdateForWorkspaceChange(scr, workspace); w_global.workspace.last_used = w_global.workspace.current; w_global.workspace.current = workspace; wWorkspaceMenuUpdate(w_global.workspace.menu); wWorkspaceMenuUpdate(w_global.clip.ws_menu); toUnmapSize = 16; toUnmapCount = 0; toUnmap = wmalloc(toUnmapSize * sizeof(WWindow *)); if ((tmp = scr->focused_window) != NULL) { if ((IS_OMNIPRESENT(tmp) && (tmp->flags.mapped || tmp->flags.shaded) && !WFLAGP(tmp, no_focusable)) || tmp->flags.changing_workspace) { foc = tmp; } /* foc2 = tmp; will fix annoyance with gnome panel * but will create annoyance for every other application */ while (tmp) { if (tmp->frame->workspace != workspace && !tmp->flags.selected) { /* unmap windows not on this workspace */ if ((tmp->flags.mapped || tmp->flags.shaded) && !IS_OMNIPRESENT(tmp) && !tmp->flags.changing_workspace) { if (toUnmapCount == toUnmapSize) { toUnmapSize *= 2; toUnmap = wrealloc(toUnmap, toUnmapSize * sizeof(WWindow *)); } toUnmap[toUnmapCount++] = tmp; } /* also unmap miniwindows not on this workspace */ if (!wPreferences.sticky_icons && tmp->flags.miniaturized && tmp->icon && !IS_OMNIPRESENT(tmp)) { XUnmapWindow(dpy, tmp->icon->core->window); tmp->icon->mapped = 0; } /* update current workspace of omnipresent windows */ if (IS_OMNIPRESENT(tmp)) { WApplication *wapp = wApplicationOf(tmp->main_window); tmp->frame->workspace = workspace; if (wapp) { wapp->last_workspace = workspace; } if (!foc2 && (tmp->flags.mapped || tmp->flags.shaded)) { foc2 = tmp; } } } else { /* change selected windows' workspace */ if (tmp->flags.selected) { wWindowChangeWorkspace(tmp, workspace); if (!tmp->flags.miniaturized && !foc) { foc = tmp; } } else { if (!tmp->flags.hidden) { if (!(tmp->flags.mapped || tmp->flags.miniaturized)) { /* remap windows that are on this workspace */ wWindowMap(tmp); if (!foc && !WFLAGP(tmp, no_focusable)) { foc = tmp; } } /* Also map miniwindow if not omnipresent */ if (!wPreferences.sticky_icons && tmp->flags.miniaturized && !IS_OMNIPRESENT(tmp) && tmp->icon) { tmp->icon->mapped = 1; XMapWindow(dpy, tmp->icon->core->window); } } } } tmp = tmp->prev; } while (toUnmapCount > 0) { wWindowUnmap(toUnmap[--toUnmapCount]); } wfree(toUnmap); /* Gobble up events unleashed by our mapping & unmapping. * These may trigger various grab-initiated focus & * crossing events. However, we don't care about them, * and ignore their focus implications altogether to avoid * flicker. */ scr->flags.ignore_focus_events = 1; ProcessPendingEvents(); scr->flags.ignore_focus_events = 0; if (!foc) foc = foc2; if (scr->focused_window->flags.mapped && !foc) { foc = scr->focused_window; } if (wPreferences.focus_mode == WKF_CLICK) { wSetFocusTo(scr, foc); } else { unsigned int mask; int foo; Window bar, win; WWindow *tmp; tmp = NULL; if (XQueryPointer(dpy, scr->root_win, &bar, &win, &foo, &foo, &foo, &foo, &mask)) { tmp = wWindowFor(win); } /* If there's a window under the pointer, focus it. * (we ate all other focus events above, so it's * certainly not focused). Otherwise focus last * focused, or the root (depending on sloppiness) */ if (!tmp && wPreferences.focus_mode == WKF_SLOPPY) { wSetFocusTo(scr, foc); } else { wSetFocusTo(scr, tmp); } } } /* We need to always arrange icons when changing workspace, even if * no autoarrange icons, because else the icons in different workspaces * can be superposed. * This can be avoided if appicons are also workspace specific. */ if (!wPreferences.sticky_icons) wArrangeIcons(scr, False); if (scr->dock) wAppIconPaint(scr->dock->icon_array[0]); if (!wPreferences.flags.noclip && (w_global.workspace.array[workspace]->clip->auto_collapse || w_global.workspace.array[workspace]->clip->auto_raise_lower)) { /* to handle enter notify. This will also */ XUnmapWindow(dpy, w_global.clip.icon->icon->core->window); XMapWindow(dpy, w_global.clip.icon->icon->core->window); } else if (w_global.clip.icon != NULL) { wClipIconPaint(); } wScreenUpdateUsableArea(scr); wNETWMUpdateDesktop(scr); showWorkspaceName(scr, workspace); WMPostNotificationName(WMNWorkspaceChanged, scr, (void *)(uintptr_t) workspace); /* XSync(dpy, False); */ }
Bool wWorkspaceDelete(WScreen * scr, int workspace) { WWindow *tmp; WWorkspace **list; int i, j; if (workspace <= 0) return False; /* verify if workspace is in use by some window */ tmp = scr->focused_window; while (tmp) { if (!IS_OMNIPRESENT(tmp) && tmp->frame->workspace == workspace) return False; tmp = tmp->prev; } if (!wPreferences.flags.noclip) { wDockDestroy(w_global.workspace.array[workspace]->clip); w_global.workspace.array[workspace]->clip = NULL; } list = wmalloc(sizeof(WWorkspace *) * (w_global.workspace.count - 1)); j = 0; for (i = 0; i < w_global.workspace.count; i++) { if (i != workspace) { list[j++] = w_global.workspace.array[i]; } else { if (w_global.workspace.array[i]->name) wfree(w_global.workspace.array[i]->name); wfree(w_global.workspace.array[i]); } } wfree(w_global.workspace.array); w_global.workspace.array = list; w_global.workspace.count--; /* update menu */ wWorkspaceMenuUpdate(w_global.workspace.menu); /* clip workspace menu */ wWorkspaceMenuUpdate(w_global.clip.ws_menu); /* update also window menu */ if (w_global.workspace.submenu) { WMenu *menu = w_global.workspace.submenu; i = menu->entry_no; while (i > w_global.workspace.count) wMenuRemoveItem(menu, --i); wMenuRealize(menu); } /* and clip menu */ if (w_global.clip.submenu) { WMenu *menu = w_global.clip.submenu; i = menu->entry_no; while (i > w_global.workspace.count) wMenuRemoveItem(menu, --i); wMenuRealize(menu); } wNETWMUpdateDesktop(scr); WMPostNotificationName(WMNWorkspaceDestroyed, scr, (void *)(uintptr_t) (w_global.workspace.count - 1)); if (w_global.workspace.current >= w_global.workspace.count) wWorkspaceChange(scr, w_global.workspace.count - 1); if (w_global.workspace.last_used >= w_global.workspace.count) w_global.workspace.last_used = 0; return True; }