static void selectWindow(WMWidget *bPtr, void *data) { InspectorPanel *panel = (InspectorPanel *) data; WWindow *wwin = panel->inspected; WScreen *scr = wwin->screen_ptr; XEvent event; WWindow *iwin; /* Parameter not used, but tell the compiler that it is ok */ (void) bPtr; if (XGrabPointer(dpy, scr->root_win, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_SELECT], CurrentTime) != GrabSuccess) { wwarning("could not grab mouse pointer"); return; } WMSetLabelText(panel->specLbl, _("Click in the window you wish to inspect.")); WMMaskEvent(dpy, ButtonPressMask, &event); XUngrabPointer(dpy, CurrentTime); iwin = wWindowFor(event.xbutton.subwindow); if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) { iwin->flags.inspector_open = 1; iwin->inspector = createInspectorForWindow(iwin, panel->frame->frame_x, panel->frame->frame_y, True); wCloseInspectorForWindow(wwin); } else { WMSetLabelText(panel->specLbl, spec_text); } }
void wApplicationDestroy(WApplication * wapp) { WWindow *wwin; WScreen *scr; if (!wapp) return; wapp->refcount--; if (wapp->refcount > 0) return; if (wapp->urgent_bounce_timer) { WMDeleteTimerHandler(wapp->urgent_bounce_timer); wapp->urgent_bounce_timer = NULL; } if (wapp->flags.bouncing) { /* event.c:handleDestroyNotify forced this destroy and thereby overlooked the bounce callback */ wapp->refcount = 1; return; } scr = wapp->main_window_desc->screen_ptr; if (wapp == scr->wapp_list) { if (wapp->next) wapp->next->prev = NULL; scr->wapp_list = wapp->next; } else { if (wapp->next) wapp->next->prev = wapp->prev; if (wapp->prev) wapp->prev->next = wapp->next; } XDeleteContext(dpy, wapp->main_window, wAppWinContext); wAppMenuDestroy(wapp->menu); /* Remove application icon */ removeAppIconFor(wapp); wwin = wWindowFor(wapp->main_window_desc->client_win); wWindowDestroy(wapp->main_window_desc); if (wwin) { /* undelete client window context that was deleted in * wWindowDestroy */ XSaveContext(dpy, wwin->client_win, wWinContext, (XPointer) & wwin->client_descriptor); } wfree(wapp); }
WApplication *wApplicationCreate(WWindow * wwin) { WScreen *scr = wwin->screen_ptr; Window main_window = wwin->main_window; WApplication *wapp; WWindow *leader; if (main_window == None || main_window == scr->root_win) return NULL; { Window root; int foo; unsigned int bar; /* check if the window is valid */ if (!XGetGeometry(dpy, main_window, &root, &foo, &foo, &bar, &bar, &bar, &bar)) return NULL; } wapp = wApplicationOf(main_window); if (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)); wapp->refcount = 1; wapp->last_focused = NULL; wapp->urgent_bounce_timer = NULL; wapp->last_workspace = 0; wapp->main_window = main_window; wapp->main_window_desc = makeMainWindow(scr, main_window); if (!wapp->main_window_desc) { wfree(wapp); return NULL; } wapp->main_window_desc->fake_group = wwin->fake_group; wapp->main_window_desc->net_icon_image = RRetainImage(wwin->net_icon_image); leader = wWindowFor(main_window); if (leader) leader->main_window = main_window; wapp->menu = wAppMenuGet(scr, main_window); #ifdef USER_MENU if (!wapp->menu) wapp->menu = wUserMenuGet(scr, wapp->main_window_desc); #endif /* Set application wide attributes from the leader */ wapp->flags.hidden = WFLAGP(wapp->main_window_desc, start_hidden); wapp->flags.emulated = WFLAGP(wapp->main_window_desc, emulate_appicon); /* application descriptor */ XSaveContext(dpy, main_window, wAppWinContext, (XPointer) wapp); create_appicon_for_application(wapp, wwin); return wapp; }
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); */ }