?? windows.c
字號:
{ MwmWindow *t; int xl = -1, yt, DragWidth, DragHeight; int gravx, gravy; /* gravity signs for positioning */ int show_feed; Boolean usePPos; get_gravity_offsets(tmp_win, &gravx, &gravy); /* Select a desk to put the window on (in list of priority): * 1. Sticky Windows stay on the current desk. * 2. Windows specified with StartsOnDesk go where specified * 3. Put it on the desk it was on before the restart. * 4. Transients go on the same desk as their parents. * 5. Window groups stay together (completely untested) */ tmp_win->Desk = scr->current_desk; if (tmp_win->flags & STICKY) tmp_win->Desk = scr->current_desk; else { Atom atype; int aformat; unsigned long nitems, bytes_remain; unsigned char *prop; if ((tmp_win->wmhints) && (tmp_win->wmhints->flags & WindowGroupHint) && (tmp_win->wmhints->window_group != None) && (tmp_win->wmhints->window_group != scr->root_win)) { /* Try to find the group leader or another window * in the group */ for (t = scr->mwm_root.next; t != NULL; t = t->next) { if ((t->w == tmp_win->wmhints->window_group) || ((t->wmhints) && (t->wmhints->flags & WindowGroupHint) && (t->wmhints->window_group == tmp_win->wmhints->window_group))) tmp_win->Desk = t->Desk; } } if ((tmp_win->flags & TRANSIENT) && (tmp_win->transientfor != None) && (tmp_win->transientfor != scr->root_win)) { /* Try to find the parent's desktop */ for (t = scr->mwm_root.next; t != NULL; t = t->next) { if (t->w == tmp_win->transientfor) tmp_win->Desk = t->Desk; } } if ((XGetWindowProperty(dpy, tmp_win->w, XA_WM_DESKTOP, 0L, 1L, True, XA_WM_DESKTOP, &atype, &aformat, &nitems, &bytes_remain, &prop)) == Success) { if (prop != NULL) { tmp_win->Desk = *(unsigned long *)prop; XFree(prop); } } } /* I think it would be good to switch to the selected desk * whenever a new window pops up, except during initialization */ if (!PPosOverride) DT_ChangeDesks(scr, 0, tmp_win->Desk); /* Desk has been selected, now pick a location for the window */ /* * If * o the window is a transient, or * * o a USPosition was requested * * then put the window where requested. * */#if 0 fprintf(stderr, "PlaceWindow: UsePPosition = %s, Hints %s%s, attr x %d y %d\n", (tmp_win->use_p_position == XmUSE_PPOSITION_ON) ? "XmUSE_PPOSITION_ON" : (tmp_win->use_p_position == XmUSE_PPOSITION_NON_ZERO) ? "XmUSE_PPOSITION_NON_ZERO" : "???", (tmp_win->hints.flags & USPosition) ? "USPosition" : "", (tmp_win->hints.flags & PPosition) ? "PPosition" : "", tmp_win->attr.x, tmp_win->attr.y);#endif if (tmp_win->use_p_position == XmUSE_PPOSITION_ON && (tmp_win->hints.flags & USPosition || tmp_win->hints.flags & PPosition)) usePPos = True; else if (tmp_win->use_p_position == XmUSE_PPOSITION_NON_ZERO && (tmp_win->hints.flags & USPosition || tmp_win->hints.flags & PPosition) && (tmp_win->attr.x != 0 || tmp_win->attr.y != 0)) usePPos = True; else usePPos = False; if (!(tmp_win->flags & TRANSIENT) && !(PPosOverride) && !(usePPos) && !((tmp_win->wmhints) && (tmp_win->wmhints->flags & StateHint) && (tmp_win->wmhints->initial_state == IconicState))) { /* Get user's window placement */ xl = -1; yt = -1; if (Mwm.client_auto_place) smart_placement(scr, tmp_win, tmp_win->frame_width + 2 * tmp_win->bw, tmp_win->frame_height + 2 * tmp_win->bw, &xl, &yt); if (xl < 0) { if (MISC_Grab(scr, POSITION_CURS)) { /* Grabbed the pointer - continue */ XGrabServer(dpy); if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, (unsigned int *)&DragWidth, (unsigned int *)&DragHeight, &JunkBW, &JunkDepth) == 0) { XtFree((char *)tmp_win); XUngrabServer(dpy); return False; } DragWidth += 2 * tmp_win->boundary_width + 2 * tmp_win->matte_width; DragHeight += tmp_win->title_height + 2 * tmp_win->boundary_width + 2 * tmp_win->matte_width; if (Mwm.show_feedback & MWM_FEEDBACK_PLACEMENT) XMapRaised(dpy, scr->size_win); show_feed = Mwm.show_feedback & MWM_FEEDBACK_MOVE; if (!(Mwm.show_feedback & MWM_FEEDBACK_PLACEMENT)) Mwm.show_feedback &= ~MWM_FEEDBACK_MOVE; MOVE_EventLoop(scr, tmp_win, 0, 0, DragWidth, DragHeight, &xl, &yt, False, True); if (Mwm.show_feedback & MWM_FEEDBACK_PLACEMENT) XUnmapWindow(dpy, scr->size_win); if (show_feed) Mwm.show_feedback |= MWM_FEEDBACK_MOVE; XUngrabServer(dpy); MISC_Ungrab(scr); } else { /* couldn't grab the pointer - better do something */ XBell(dpy, scr->screen); xl = 0; yt = 0; } } tmp_win->attr.y = yt - tmp_win->old_bw + tmp_win->bw; tmp_win->attr.x = xl - tmp_win->old_bw + tmp_win->bw; tmp_win->xdiff = xl; tmp_win->ydiff = yt; } else { /* the USPosition was specified, or the window is a transient, * or it starts iconic so place it automatically */ tmp_win->xdiff = tmp_win->attr.x; tmp_win->ydiff = tmp_win->attr.y; /* put it where asked, mod title bar */ /* if the gravity is towards the top, move it by the title height */ tmp_win->attr.y -= gravy * (tmp_win->bw - tmp_win->old_bw); tmp_win->attr.x -= gravx * (tmp_win->bw - tmp_win->old_bw); if (gravy > 0) tmp_win->attr.y -= tmp_win->title_height + 2 * tmp_win->boundary_width + 2 * tmp_win->matte_width; if (gravx > 0) tmp_win->attr.x -= 2 * tmp_win->boundary_width + 2 * tmp_win->matte_width; } return True;}/* * add a new window to the mwm list */static MwmWindow *add_window(ScreenInfo *scr, Window w){ MwmWindow *tmp_win; /* new mwm window structure */ int i, width, height, tx, ty; int xws, yws, xbs, ybs; unsigned wws, hws, wbs, hbs; int boundingShaped, clipShaped; XTextProperty text_prop; NeedToResizeToo = False; /* allocate space for the mwm window */ tmp_win = (MwmWindow *)XtCalloc(1, sizeof(MwmWindow)); if (tmp_win == NULL) { return NULL; } tmp_win->w = w; tmp_win->classhint.res_name = NoName; tmp_win->classhint.res_class = NoName; XGetClassHint(dpy, tmp_win->w, &tmp_win->classhint); if (tmp_win->classhint.res_name == NULL) tmp_win->classhint.res_name = NoName; if (tmp_win->classhint.res_class == NULL) tmp_win->classhint.res_class = NoName; RES_GetClientDefaults(scr, tmp_win, tmp_win->classhint.res_name, tmp_win->classhint.res_class); if (XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) { XtFree((char *)tmp_win); return (NULL); } PROP_GetWmProtocols(tmp_win); PROP_GetWmColormapWindows(tmp_win); if (!(XGetWindowAttributes(dpy, tmp_win->w, &(tmp_win->attr)))) tmp_win->attr.colormap = scr->mwm_root.attr.colormap; if (XGetWMName(dpy, tmp_win->w, &text_prop) != 0) tmp_win->name = (char *)text_prop.value; else tmp_win->name = NoName; tmp_win->wmhints = XGetWMHints(dpy, tmp_win->w); if (XGetTransientForHint(dpy, tmp_win->w, &tmp_win->transientfor)) tmp_win->flags |= TRANSIENT; else tmp_win->flags &= ~TRANSIENT; tmp_win->old_bw = tmp_win->attr.border_width; XShapeSelectInput(dpy, tmp_win->w, ShapeNotifyMask); XShapeQueryExtents(dpy, tmp_win->w, &boundingShaped, &xws, &yws, &wws, &hws, &clipShaped, &xbs, &ybs, &wbs, &hbs); tmp_win->wShaped = boundingShaped; tmp_win->title_height = scr->components[MWM_TITLE_A].f_height + 3 + tmp_win->bw; PROP_GetWmIconName(tmp_win); PROP_GetMwmHints(tmp_win); DEC_SelectDecorations(scr, tmp_win); if ((tmp_win->wmhints) && (tmp_win->wmhints->flags & (IconWindowHint | IconPixmapHint))) { /* window has its own icon */ tmp_win->icon_bitmap_file = NULL; } /* use default icon if nothing specified */ else if (tmp_win->icon_image == NULL) tmp_win->icon_bitmap_file = scr->DefaultIcon; PROP_GetWindowSizeHints(tmp_win); /* Tentative size estimate */ tmp_win->frame_width = tmp_win->attr.width + 2 * tmp_win->boundary_width + 2 * tmp_win->matte_width; tmp_win->frame_height = tmp_win->attr.height + tmp_win->title_height + 2 * tmp_win->boundary_width + 2 * tmp_win->matte_width; WIN_ConstrainWindow(scr, tmp_win, &tmp_win->frame_width, &tmp_win->frame_height); if (!place_window(scr, tmp_win)) return NULL; /* * Make sure the client window still exists. We don't want to leave an * orphan frame window if it doesn't. Since we now have the server * grabbed, the window can't disappear later without having been * reparented, so we'll get a DestroyNotify for it. We won't have * gotten one for anything up to here, however. */ XGrabServer(dpy); if (XGetGeometry(dpy, w, &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth) == 0) { XtFree((char *)tmp_win); XUngrabServer(dpy); return (NULL); } XSetWindowBorderWidth(dpy, tmp_win->w, 0); if (tmp_win->icon_label == NULL) tmp_win->icon_label = tmp_win->classhint.res_name; tmp_win->icon_active_label = tmp_win->name; tmp_win->flags &= ~ICONIFIED; tmp_win->flags &= ~ICON_UNMAPPED; tmp_win->flags &= ~MAXIMIZED; /* add the window into the mwm list */ MISC_AddToTree(scr, tmp_win); DEC_CreateDecorations(scr, tmp_win); if (XGetWMName(dpy, tmp_win->w, &text_prop) != 0) tmp_win->name = (char *)text_prop.value; else tmp_win->name = NoName; if (tmp_win->w != scr->pager_win && tmp_win->w != scr->restart_win && tmp_win->w != scr->quit_win && tmp_win->w != scr->toggle_win) XAddToSaveSet(dpy, tmp_win->w); /* * Reparenting generates an UnmapNotify event, followed by a MapNotify. * Set the map state to False to prevent a transition back to * WithdrawnState in HandleUnmapNotify. Map state gets set correctly * again in HandleMapNotify. */ tmp_win->flags &= ~MAPPED; width = tmp_win->frame_width; tmp_win->frame_width = 0; height = tmp_win->frame_height; tmp_win->frame_height = 0; DEC_ConfigureDecorations(scr, tmp_win, tmp_win->frame_x, tmp_win->frame_y, width, height, True); /* wait until the window is iconified and the icon window is mapped * before creating the icon window */ tmp_win->icon_w = None; grab_buttons(scr, tmp_win); grab_keys(scr, tmp_win); save_context(tmp_win); PROP_GetMwmMenu(tmp_win); MENU_BuildWindowMenu(scr, tmp_win); PROP_GetMwmMessages(tmp_win); WIN_Raise(scr, tmp_win); XUngrabServer(dpy); XGetGeometry(dpy, tmp_win->w, &JunkRoot, &JunkX, &JunkY, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth); XTranslateCoordinates(dpy, tmp_win->frame, scr->root_win, JunkX, JunkY, &tx, &ty, &JunkChild); tmp_win->xdiff -= tx; tmp_win->ydiff -= ty; if (Mwm.keyboard_focus_policy == XmEXPLICIT) { /* need to grab all buttons for window that we are about to * unhighlight */ for (i = 0; i < 3; i++) if (scr->buttons2grab & (1 << i)) { XGrabButton(dpy, (i + 1), 0, tmp_win->frame, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, scr->cursors[SYS_CURS]); XGrabButton(dpy, (i + 1), LockMask, tmp_win->frame, True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, scr->cursors[SYS_CURS]); } } PROP_GetWmProtocols(tmp_win); PROP_GetWmColormapWindows(tmp_win); if (!(XGetWindowAttributes(dpy, tmp_win->w, &(tmp_win->attr)))) tmp_win->attr.colormap = scr->mwm_root.attr.colormap; if (NeedToResizeToo) { int show_feed; XWarpPointer(dpy, scr->root_win, scr->root_win, 0, 0, scr->d_width, scr->d_height, tmp_win->frame_x + (tmp_win->frame_width >> 1), tmp_win->frame_y + (tmp_win->frame_height >> 1)); show_feed = Mwm.show_feedback & MWM_FEEDBACK_RESIZE; if (!(Mwm.show_feedback & MWM_FEEDBACK_PLACEMENT)) Mwm.show_feedback &= ~MWM_FEEDBACK_RESIZE; RESIZE_EventLoop(scr, tmp_win->w, tmp_win, 0, 0, 0, 0); if (show_feed) Mwm.show_feedback |= MWM_FEEDBACK_RESIZE; } COLOR_InstallWindowColorMap(scr, scr->mwm_colormap); return (tmp_win);}/* * release a window and the subs */static voidrelease_window(ScreenInfo *scr, MwmWindow *win){ MwmWindow *tmp; for (tmp = win->child; tmp != NULL; tmp = tmp->next) release_window(scr, tmp); XUnmapWindow(dpy, win->frame); WIN_RestoreWithdrawn(scr, win, True); XDestroyWindow(dpy, win->frame);}/* * count the transient children of a window */static intcount_transients(ScreenInfo *scr, MwmWindow *win){ MwmWindow *tmp; int count = 0; for (tmp = win->child; tmp != NULL; tmp = tmp->next) { count++; count += count_transients(scr, tmp); if ((scr->pager_win) && !(tmp->flags & STICKY)) XRaiseWindow(dpy, tmp->pager_view); if ((tmp->flags & ICONIFIED)) { count += 2; } } return count;}/* * gather up the transients */static voidgather_transients(MwmWindow *win, Window *wins, int *count){ MwmWindow *tmp; for (tmp = win->child; tmp != NULL; tmp = tmp->next) gather_transients(tmp, wins, count); for (tmp = win->child; tmp != NULL; tmp = tmp->next) { wins[(*count)++] = tmp->frame;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -