📄 events.c
字号:
(MouseEntry->count == 0) && (MouseEntry->context & scr->event_context) && (MouseEntry->modifier == AnyModifier || MouseEntry->modifier == (modifier & (~LockMask))) && (MouseEntry->mask & ButtonReleaseMask)) { /* got a match, now process it */ if (MouseEntry->func != F_NOP) { Action = MouseEntry->item ? MouseEntry->item->action : NULL; FUNC_Execute(scr, MouseEntry->func, Action, event->xany.window, win, event, scr->event_context, MouseEntry->val1, MouseEntry->val2, MouseEntry->val1_unit, MouseEntry->val2_unit, MouseEntry->menu); break; } } MouseEntry = MouseEntry->next; }}/* * EnterNotify event handler */static voidenter_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XEnterWindowEvent *ewp = &event->xcrossing; XEvent d; /* look for a matching leaveNotify which would nullify this enterNotify */ if (XCheckTypedWindowEvent(dpy, ewp->window, LeaveNotify, &d)) { MISC_StashEventTime(&d); if ((d.xcrossing.mode == NotifyNormal) && (d.xcrossing.detail != NotifyInferior)) return; } /* an EnterEvent in one of the PanFrameWindows activates the Paging */ if (PAN_IsPannerWindow(scr, ewp->window)) { int delta_x = 0, delta_y = 0; /* this was in the HandleMotionNotify before, HEDU */ PAN_PanDesktop(scr, scr->edge_scroll_x, scr->edge_scroll_y, &event->xcrossing.x_root, &event->xcrossing.y_root, &delta_x, &delta_y, True, event); return; } if (event->xany.window == scr->root_win) { if (!(Mwm.keyboard_focus_policy == XmEXPLICIT)) { WIN_SetFocus(scr, scr->no_focus_win, NULL); MISC_SetFocusSequence(scr); } if (Mwm.colormap_focus_policy != XmKEYBOARD) COLOR_InstallWindowColorMap(scr, NULL); return; } /* make sure its for one of our windows */ if (!win) return; if (!(Mwm.keyboard_focus_policy == XmEXPLICIT)) { if (scr->mwm_focus != win) { if ((Mwm.auto_raise_delay > 0) && (!(win->flags & VISIBLE))) MISC_SetTimer(Mwm.auto_raise_delay); WIN_SetFocusInTree(win); WIN_SetFocus(scr, win->w, win); MISC_SetFocusSequence(scr); } else { WIN_SetFocusInTree(win); WIN_SetFocus(scr, win->w, win); } } if (Mwm.colormap_focus_policy == XmPOINTER) { if ((!(win->flags & ICONIFIED)) && (event->xany.window == win->w)) COLOR_InstallWindowColorMap(scr, win); else COLOR_InstallWindowColorMap(scr, NULL); }}/* * LeaveNotify event handler */static voidleave_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ /* If we leave the root window, then we're really moving * another screen on a multiple screen display, and we * need to de-focus and unhighlight to make sure that we * don't end up with more than one highlighted window at a time */ if (event->xcrossing.window == scr->root_win) { if (event->xcrossing.mode == NotifyNormal) { if (event->xcrossing.detail != NotifyInferior) { if (scr->mwm_focus != NULL) { WIN_SetFocus(scr, scr->no_focus_win, NULL); } if (scr->mwm_highlight != NULL) DEC_DrawDecorations(scr, scr->mwm_highlight, False, True, True, None); } } }}/* * ConfigureRequest event handler */static voidconfigure_request(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XWindowChanges xwc; unsigned long xwcm; int x, y, width, height; XConfigureRequestEvent *cre = &event->xconfigurerequest; /* * event->xany.window is event->xconfigurerequest.parent, so win will * be wrong */ event->xany.window = cre->window; /* mash parent field */ if (XFindContext(dpy, cre->window, MwmContext, (XPointer *)&win) == XCNOENT) win = NULL; /* * According to the July 27, 1988 ICCCM draft, we should ignore size and * position fields in the WM_NORMAL_HINTS property when we map a window. * Instead, we'll read the current geometry. Therefore, we should respond * to configuration requests for windows which have never been mapped. */ if (!win || (win->icon_w == cre->window)) { xwcm = cre->value_mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth); xwc.x = cre->x; xwc.y = cre->y; if ((win) && ((win->icon_w == cre->window))) { win->icon_xl_loc = cre->x; win->icon_x_loc = cre->x + (win->icon_w_width - win->icon_p_width) / 2; win->icon_y_loc = cre->y - win->icon_p_height; } xwc.width = cre->width; xwc.height = cre->height; xwc.border_width = cre->border_width; XConfigureWindow(dpy, event->xany.window, xwcm, &xwc); if (win) { xwc.x = win->icon_x_loc; xwc.y = win->icon_y_loc - win->icon_p_height; xwcm = cre->value_mask & (CWX | CWY); if (win->icon_pixmap_w != None) XConfigureWindow(dpy, win->icon_pixmap_w, xwcm, &xwc); xwc.x = win->icon_x_loc; xwc.y = win->icon_y_loc; xwcm = cre->value_mask & (CWX | CWY); if (win->icon_w != None) XConfigureWindow(dpy, win->icon_w, xwcm, &xwc); } return; } if (cre->value_mask & CWStackMode) { MwmWindow *otherwin; xwc.sibling = (((cre->value_mask & CWSibling) && (XFindContext(dpy, cre->above, MwmContext, (XPointer *)&otherwin) == XCSUCCESS)) ? otherwin->frame : cre->above); xwc.stack_mode = cre->detail; XConfigureWindow(dpy, win->frame, cre->value_mask & (CWSibling | CWStackMode), &xwc); } { int xws, yws, xbs, ybs; unsigned wws, hws, wbs, hbs; int boundingShaped, clipShaped; XShapeQueryExtents(dpy, win->w, &boundingShaped, &xws, &yws, &wws, &hws, &clipShaped, &xbs, &ybs, &wbs, &hbs); win->wShaped = boundingShaped; } /* Don't modify frame_XXX fields before calling SetupWindow! */ x = win->frame_x; y = win->frame_y; width = win->frame_width; height = win->frame_height; /* for restoring */ if (cre->value_mask & CWBorderWidth) { win->old_bw = cre->border_width; } /* override even if border change */ if (cre->value_mask & CWX) x = cre->x - win->boundary_width - win->bw - win->matte_width; if (cre->value_mask & CWY) y = cre->y - win->boundary_width - win->title_height - win->bw - win->matte_width; if (cre->value_mask & CWWidth) width = cre->width + 2 * win->boundary_width + 2 * win->matte_width; if (cre->value_mask & CWHeight) height = cre->height + win->title_height + 2 * win->boundary_width + 2 * win->matte_width; /* * SetupWindow (x,y) are the location of the upper-left outer corner and * are passed directly to XMoveResizeWindow (frame). The (width,height) * are the inner size of the frame. The inner width is the same as the * requested client window width; the inner height is the same as the * requested client window height plus any title bar slop. */ DEC_ConfigureDecorations(scr, win, x, y, width, height, False); PAGER_Clear(scr);}/* * record fully visible windows for use in the RaiseLower function and the * OnTop type windows. */static voidvisibility_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XVisibilityEvent *vevent = (XVisibilityEvent *)event; if (win) { if (vevent->state == VisibilityUnobscured) win->flags |= VISIBLE; else win->flags &= ~VISIBLE; }}/* * shape notification event handler */static voidshape_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ XShapeEvent *sev = (XShapeEvent *) & event; if (!win) return; if (sev->kind != ShapeBounding) return; win->wShaped = sev->shaped; DEC_SetShape(win, win->frame_width);}/* * event handling initialization */voidEVENT_Initialize(void){ XShapeQueryExtension(dpy, &ShapeEventBase, &ShapeErrorBase);}/* * return the window context for an XEvent. */intEVENT_GetContext(ScreenInfo *scr, MwmWindow *t, XEvent *e, Window *w){ int ctxt, i; if (!t) return C_ROOT; ctxt = C_NO_CONTEXT; *w = e->xany.window; if (*w == scr->no_focus_win) return C_ROOT; /* Since key presses and button presses are grabbed in the frame * when we have re-parented windows, we need to find out the real * window where the event occured */ if ((e->type == KeyPress) && (e->xkey.subwindow != None)) *w = e->xkey.subwindow; if ((e->type == ButtonPress) && (e->xbutton.subwindow != None) && ((e->xbutton.subwindow == t->w) || (e->xbutton.subwindow == t->parent))) *w = e->xbutton.subwindow; if (*w == scr->root_win) ctxt = C_ROOT; if (t) { if (*w == t->title) ctxt = C_TITLE; if ((*w == t->w) || (*w == t->parent)) ctxt = C_WINDOW; if (*w == t->icon_w) ctxt = C_ICON; if (*w == t->icon_pixmap_w) ctxt = C_ICON; if (*w == t->frame) ctxt = C_FRAME; for (i = 0; i < 4; i++) if (*w == t->corners[i]) { ctxt = C_FRAME; } for (i = 0; i < 4; i++) if (*w == t->sides[i]) { ctxt = C_FRAME; } if (*w == t->menub) { ctxt = C_MENUB; } if (*w == t->minimizeb) { ctxt = C_MINIMIZEB; } if (*w == t->maximizeb) { ctxt = C_MAXIMIZEB; } } return ctxt;}/* * Waits for next X event, or for an auto-raise timeout. */intEVENT_Next(XEvent *event){#ifndef HAVE_GETITIMER struct itimerval { struct timeval it_value; };#endif struct itimerval value; fd_set in_fdset, out_fdset; Window child; int retval, i; ScreenInfo *scr; /* Do this prior to the select() call, in case the timer already expired, * in which case the select would never return. */ if (alarmed) { alarmed = False; for (i = 0; i < Mwm.number_of_screens; i++) { scr = Mwm.screen_info[i]; XQueryPointer(dpy, scr->root_win, &JunkRoot, &child, &JunkX, &JunkY, &JunkX, &JunkY, &JunkMask); if ((scr->mwm_focus != NULL) && (child == scr->mwm_focus->frame)) { if (!(scr->mwm_focus->flags & VISIBLE) && scr->mwm_focus->focus_auto_raise) { WIN_Raise(scr, scr->mwm_focus); PAGER_Clear(scr); } } } return 0; }#ifdef HAVE_GETITIMER getitimer(ITIMER_REAL, &value);#else value.it_value.tv_usec = 10000; value.it_value.tv_sec = 0;#endif FD_ZERO(&in_fdset); FD_SET(x_fd, &in_fdset); FD_ZERO(&out_fdset); /* Do this IMMEDIATELY prior to select, to prevent any nasty * queued up X events from just hanging around waiting to be * flushed */ XFlush(dpy); if (XPending(dpy)) { XNextEvent(dpy, event); MISC_StashEventTime(event); return 1; } /* Zap all those zombies! */ /* If we get to here, then there are no X events waiting to be processed. * Just take a moment to check for dead children. */ ReapChildren(); XFlush(dpy); if ((value.it_value.tv_usec != 0) || (value.it_value.tv_sec != 0)) {#ifdef __hpux retval = select(fd_width, (int *)&in_fdset, 0, 0, &value.it_value);#else retval = select(fd_width, &in_fdset, 0, 0, &value.it_value);#endif } else {#ifdef __hpux retval = select(fd_width, (int *)&in_fdset, (int *)&out_fdset, 0, NULL);#else retval = select(fd_width, &in_fdset, &out_fdset, 0, NULL);#endif } return 0;}/* * handle a single X event stored in global var Event */voidEVENT_Dispatch(XEvent *event){ Window w = event->xany.window; Widget wid; ScreenInfo *scr; MwmWindow *win; MISC_StashEventTime(event); scr = SCREEN_EventToStruct(event); if (XFindContext(dpy, w, MwmContext, (XPointer *)&win) == XCNOENT) win = NULL; if ((wid = XtWindowToWidget(event->xany.display, w)) != NULL) { Boolean ret; if (event->xany.type == MapNotify && XtIsShell(wid)) { map_request(scr, win, event); map_notify(scr, win, event); } if (event->xany.type == UnmapNotify && XtIsShell(wid)) unmap_notify(scr, win, event);#if XtSpecificationRelease >= 6 ret = XtDispatchEventToWidget(wid, event);#else ret = XtDispatchEvent(event);#endif if (ret) return; } switch (event->type) { case Expose: expose(scr, win, event); break; case DestroyNotify: destroy_notify(scr, win, event); break; case MapRequest: map_request(scr, win, event); break; case MapNotify: map_notify(scr, win, event); break; case UnmapNotify: unmap_notify(scr, win, event); break; case MotionNotify: motion_notify(scr, win, event); break; case ButtonPress: button_press(scr, win, event); break; case ButtonRelease: button_release(scr, win, event); break; case EnterNotify: enter_notify(scr, win, event); break; case LeaveNotify: leave_notify(scr, win, event); break; case FocusIn: focus_in(scr, win, event); break; case FocusOut: focus_out(scr, win, event); break; case ConfigureRequest: configure_request(scr, win, event); break; case ClientMessage: client_message(scr, win, event); break; case PropertyNotify: property_notify(scr, win, event); break; case KeyPress: key_press(scr, win, event); break; case VisibilityNotify: visibility_notify(scr, win, event); break; case ColormapNotify: color_map_notify(scr, win, event); break; default: if (event->type == (ShapeEventBase + ShapeNotify)) shape_notify(scr, win, event); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -