📄 events.c
字号:
* MapRequest event handler */static voidmap_request(ScreenInfo *scr, MwmWindow *win, XEvent *event){ WIN_MapWindow(scr, event->xmaprequest.window);}/* * MapNotify event handler */static voidmap_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ if (!win) return; /* * Need to do the grab to avoid race condition of having server send * MapNotify to client before the frame gets mapped; this is bad because * the client would think that the window has a chance of being viewable * when it really isn't. */ XGrabServer(dpy); if (win->icon_w) XUnmapWindow(dpy, win->icon_w); if (win->icon_pixmap_w != None) XUnmapWindow(dpy, win->icon_pixmap_w); if (win->mwm_hints && (win->mwm_hints->flags & MWM_HINTS_INPUT_MODE) && (win->mwm_hints->input_mode == MWM_INPUT_SYSTEM_MODAL)) { XMapRaised(dpy, scr->shield_win); WIN_Raise(scr, win); } XMapSubwindows(dpy, win->frame); if (win->Desk == scr->current_desk) { XMapWindow(dpy, win->frame); } if (Mwm.keyboard_focus_policy == XmEXPLICIT && Mwm.startup_key_focus) { WIN_SetFocusInTree(win); WIN_SetFocus(scr, win->w, win); MISC_SetFocusSequence(scr); } if ((!(win->decorations & (MWM_DECOR_BORDER | MWM_DECOR_TITLE))) && (win->boundary_width < 2)) { DEC_DrawDecorations(scr, win, False, True, True, win->frame); } XSync(dpy, 0); XUngrabServer(dpy); XFlush(dpy); win->flags |= MAPPED; win->flags &= ~MAP_PENDING; win->flags &= ~ICONIFIED; win->flags &= ~ICON_UNMAPPED;}/* * UnmapNotify event handler */static voidunmap_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ int dstx, dsty; Window dumwin; XEvent dummy; /* * The July 27, 1988 ICCCM spec states that a client wishing to switch * to WithdrawnState should send a synthetic UnmapNotify with the * event field set to (pseudo-)root, in case the window is already * unmapped (which is the case for mwm for IconicState). Unfortunately, * we looked for the MwmContext using that field, so try the window * field also. */ if (!win) { event->xany.window = event->xunmap.window; if (XFindContext(dpy, event->xany.window, MwmContext, (XPointer *)&win) == XCNOENT) win = NULL; } if (!win) return; if (win->mwm_hints && (win->mwm_hints->flags & MWM_HINTS_INPUT_MODE) && (win->mwm_hints->input_mode == MWM_INPUT_SYSTEM_MODAL)) { XUnmapWindow(dpy, scr->shield_win); } if (win == scr->mwm_highlight) scr->mwm_highlight = NULL; if (scr->mwm_last_focus == win) scr->mwm_last_focus = NULL; if (win == scr->mwm_focus && Mwm.keyboard_focus_policy == XmEXPLICIT && Mwm.auto_key_focus) { if (win->next) { WIN_SetFocusInTree(win->next); WIN_SetFocus(scr, win->next->w, win->next); } else if (win->ancestor) { WIN_SetFocusInTree(win->ancestor); WIN_SetFocus(scr, win->ancestor->w, win->ancestor); } else { WIN_SetFocus(scr, scr->no_focus_win, NULL); } } if (scr->mwm_focus == win) { WIN_SetFocus(scr, scr->no_focus_win, NULL); } if (win == scr->mwm_pushed) scr->mwm_pushed = NULL; MISC_SetFocusSequence(scr); if (win == scr->mwm_colormap) scr->mwm_colormap = NULL; if (!(win->flags & MAPPED) && !(win->flags & ICONIFIED)) return; XGrabServer(dpy); if (XCheckTypedWindowEvent(dpy, event->xunmap.window, DestroyNotify, &dummy)) { /* here was the problem with the menu focus. If the * destroy notify happened later, we need to reset the focus, * as the application has had a window of opportunity to steal it * back. */ WIN_DestroyWindow(scr, win); XUngrabServer(dpy); return; } /* * The program may have unmapped the client window, from either * NormalState or IconicState. Handle the transition to WithdrawnState. * * We need to reparent the window back to the root (so that mwm exiting * won't cause it to get mapped) and then throw away all state (pretend * that we've received a DestroyNotify). */ if (XTranslateCoordinates(dpy, event->xunmap.window, scr->root_win, 0, 0, &dstx, &dsty, &dumwin)) { XEvent ev; Bool reparented; reparented = XCheckTypedWindowEvent(dpy, event->xunmap.window, ReparentNotify, &ev); PROP_SetState(win, WithdrawnState); if (reparented) { if (win->old_bw) XSetWindowBorderWidth(dpy, event->xunmap.window, win->old_bw); if (win->wmhints && (win->wmhints->flags & IconWindowHint)) XUnmapWindow(dpy, win->wmhints->icon_window); } else WIN_RestoreWithdrawn(scr, win, False); if (event->xunmap.window != scr->restart_win && event->xunmap.window != scr->quit_win && event->xunmap.window != scr->toggle_win) { XRemoveFromSaveSet(dpy, event->xunmap.window); XSelectInput(dpy, event->xunmap.window, NoEventMask); } else XDeleteContext(dpy, event->xunmap.window, MwmContext); WIN_DestroyWindow(scr, win); /* do not need to mash event before */ } /* else window no longer exists and we'll get a destroy notify */ XUngrabServer(dpy); XFlush(dpy);}/* * MotionNotify event handler */static voidmotion_notify(ScreenInfo *scr, MwmWindow *win, XEvent *event){ /* here is the code for dragging the viewport around within the pager. */ if ((win) && (win->w == scr->pager_win) && (!(win->flags & ICONIFIED))) { if (event->xmotion.state == Button3MotionMask) { EnablePagerRedraw = False; PAGER_SwitchPage(scr, False, False, event); } }}/* * ButtonPress event handler */static voidbutton_press(ScreenInfo *scr, MwmWindow *win, XEvent *event){ unsigned int modifier; MouseButton *MouseEntry; char *Action; Window x; int LocalContext; static Time last_time = 0; Boolean click = False, click2 = False, match = False; if (event->xbutton.window == scr->shield_win) { XBell(dpy, 100); return; } /* click to focus stuff goes here */ if ((Mwm.keyboard_focus_policy == XmEXPLICIT) && (win != scr->mwm_grabbing) && ((event->xbutton.state & (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0)) { if (win) { WIN_SetFocusInTree(win); WIN_SetFocus(scr, win->w, win); MISC_SetFocusSequence(scr); if (win->focus_auto_raise) { WIN_Raise(scr, win); } /* Why is this here? Seems to cause breakage with * non-focusing windows! */ if (!(win->flags & ICONIFIED)) { XSync(dpy, 0); XAllowEvents(dpy, ReplayPointer, CurrentTime); XSync(dpy, 0); return; } } } XSync(dpy, 0); XAllowEvents(dpy, ReplayPointer, CurrentTime); XSync(dpy, 0); /* here is the code for moving windows in the pager. */ if ((win) && (win->w == event->xbutton.window) && (win->w == scr->pager_win) && (event->xbutton.button == Button2)) { PAGER_Update(scr, event); return; } if ((win) && (win->w == scr->pager_win) && (!(win->flags & ICONIFIED)) && (event->xbutton.button == Button3) && (event->xany.window == scr->pager_win)) { EnablePagerRedraw = False; PAGER_SwitchPage(scr, False, False, event); } scr->event_context = EVENT_GetContext(scr, win, event, &scr->pressed_win); LocalContext = scr->event_context; x = scr->pressed_win; if (scr->event_context == C_TITLE) { DEC_DrawTitleBar(scr, win, (scr->mwm_highlight == win), False); } else { DEC_DrawDecorations(scr, win, (scr->mwm_highlight == win), True, True, scr->pressed_win); } scr->mwm_event = win; /* we have to execute a function or pop up a menu */ modifier = (event->xbutton.state & MOD_MASK); /* need to search for an appropriate mouse binding */ click = is_click(scr, event->xbutton.x, event->xbutton.y, event); if (click && (MISC_FetchEventTime() - last_time) < Mwm.double_click_time) { click2 = True; } last_time = MISC_FetchEventTime(); /* * This loop only seems to handle double-clicked stuff */ MouseEntry = scr->buttons; while (click2 && MouseEntry != (MouseButton *)0) { if ((MouseEntry->button == event->xbutton.button || MouseEntry->button == 0) && (MouseEntry->context & scr->event_context) && (MouseEntry->modifier == AnyModifier || MouseEntry->modifier == (modifier & (~LockMask))) && (MouseEntry->mask & (ButtonPressMask | ButtonReleaseMask))) { /* got a match, now process it */ if (MouseEntry->func != F_NOP) { if (MouseEntry->count == 2) { match = True; 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); } } } MouseEntry = MouseEntry->next; } /* Still only for double-clicks as "match" can only be set in the loop */ if (match) { scr->pressed_win = None; if (LocalContext != C_TITLE) { DEC_DrawDecorations(scr, scr->mwm_event, (scr->mwm_highlight == scr->mwm_event), True, True, x); } else { DEC_DrawTitleBar(scr, scr->mwm_event, (scr->mwm_highlight == scr->mwm_event), False); } scr->mwm_event = NULL; return; } /* * If we had a match above (in double-clicks), we don't come here. * * Now we traverse the list of button bindings. * * Careful inspection of mwmparse.y reveals that this is made up from * two sources: builtin bindings, and bindings read from the configuration * file. * * FIX ME the builtins are not completely motif compliant (e.g. the window * menu that's tied to <Btn1Down> on the root window). * BTW the builtins are defined in mwm.h. */ MouseEntry = scr->buttons; while (MouseEntry != (MouseButton *)0) { if ((MouseEntry->button == event->xbutton.button || MouseEntry->button == 0) && (MouseEntry->context & scr->event_context) && (MouseEntry->modifier == AnyModifier || MouseEntry->modifier == (modifier & (~LockMask))) && (MouseEntry->mask & ButtonPressMask)) { /* got a match, now process it, unless the user clicked, and it's * interactive */ /* * Rewrote the test below so I can understand it. Is it just me? */#if 1 if (MouseEntry->func == F_NOP) { MouseEntry = MouseEntry->next; continue; } if (click && !click2 && (MouseEntry->func == F_MOVE || MouseEntry->func == F_RESIZE || MouseEntry->func == F_POPUP || MouseEntry->func == F_WINDOWLIST || MouseEntry->func == F_W_POPUP)) { MouseEntry = MouseEntry->next; continue; }#else /* Uh oh. */ if (MouseEntry->func != F_NOP && !(click && !click2 && (MouseEntry->func == F_MOVE || MouseEntry->func == F_RESIZE || MouseEntry->func == F_WINDOWLIST || MouseEntry->func == F_POPUP || MouseEntry->func == F_W_POPUP)))#endif { if (!(MouseEntry->mask & ButtonReleaseMask) && MouseEntry->count == 0) { 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); } } } MouseEntry = MouseEntry->next; }#if 1 /* Hack. Support a single button press only for F_W_POPUP */ MouseEntry = scr->buttons; while (!click && !click2 && MouseEntry != (MouseButton *)0) { if ((MouseEntry->button == event->xbutton.button || MouseEntry->button == 0) && (MouseEntry->context & scr->event_context) && (MouseEntry->modifier == AnyModifier || MouseEntry->modifier == (modifier & (~LockMask))) && (MouseEntry->mask & (ButtonPressMask | ButtonReleaseMask))) { /* got a match, now process it */ if (MouseEntry->func == F_W_POPUP) {#if 0 if (MouseEntry->count == 1)#endif { Action = MouseEntry->item ? MouseEntry->item->action : NULL; /* win->custom_menu = NULL; */ /* FIX ME */ if (MouseEntry->menu == NULL) MouseEntry->menu = (MenuRoot *)DEFAULT_WIN_MENU_NAME; FUNC_Execute(scr, F_W_POPUP, Action, event->xany.window, win, event, scr->event_context, MouseEntry->val1, MouseEntry->val2, MouseEntry->val1_unit, MouseEntry->val2_unit, MouseEntry->menu); } } } MouseEntry = MouseEntry->next; }#endif /* This only works for clicks, not for <Btn1Down> */ MouseEntry = scr->buttons; while (click && !click2 && MouseEntry != (MouseButton *)0) { if ((MouseEntry->button == event->xbutton.button || MouseEntry->button == 0) && (MouseEntry->context & scr->event_context) && (MouseEntry->modifier == AnyModifier || MouseEntry->modifier == (modifier & (~LockMask))) && (MouseEntry->mask & (ButtonPressMask | ButtonReleaseMask))) { /* got a match, now process it */ if (MouseEntry->func != F_NOP) { if (MouseEntry->count == 1) { 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); } } } MouseEntry = MouseEntry->next; } scr->pressed_win = None; if (LocalContext != C_TITLE) { DEC_DrawDecorations(scr, scr->mwm_event, (scr->mwm_highlight == scr->mwm_event), True, True, x); } else { DEC_DrawTitleBar(scr, scr->mwm_event, (scr->mwm_highlight == scr->mwm_event), False); } scr->mwm_event = NULL;}/* * ButtonRelease event handler */static voidbutton_release(ScreenInfo *scr, MwmWindow *win, XEvent *event){ unsigned int modifier; MouseButton *MouseEntry; char *Action; if ((win) && (event->xany.window == scr->pager_win) && (!(win->flags & ICONIFIED))) { switch (event->xbutton.button) { default: case Button1: PAGER_SwitchPage(scr, True, True, event); break; case Button3: EnablePagerRedraw = True; PAGER_SwitchPage(scr, False, False, event); PAGER_Clear(scr); break; } } scr->event_context = EVENT_GetContext(scr, win, event, &scr->pressed_win); modifier = (event->xbutton.state & MOD_MASK); /* need to search for an appropriate mouse binding */ MouseEntry = scr->buttons; while (MouseEntry != (MouseButton *)0) { if ((MouseEntry->button == event->xbutton.button || MouseEntry->button == 0) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -