static void __focus_grab_one_button( FvwmWindow *fw, int button, int grab_buttons) { Bool do_grab; do_grab = (grab_buttons & (1 << button)); if ((do_grab & (1 << button)) == (fw->grabbed_buttons & (1 << button))) { return; } if (do_grab) { XGrabButton( dpy, button + 1, AnyModifier, FW_W_PARENT(fw), True, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None); /* Set window flags accordingly as we grab or ungrab. */ fw->grabbed_buttons |= (1 << button); } else { XUngrabButton(dpy, button + 1, AnyModifier, FW_W_PARENT(fw)); fw->grabbed_buttons &= ~(1 << button); } return; }
/* * Defer the execution of a function to the next button press if the context is * C_ROOT * * Inputs: * cursor - the cursor to display while waiting */ static Bool DeferExecution( exec_context_changes_t *ret_ecc, exec_context_change_mask_t *ret_mask, cursor_t cursor, int trigger_evtype, int do_allow_unmanaged) { int done; int finished = 0; int just_waiting_for_finish = 0; Window dummy; Window original_w; static XEvent e; Window w; int wcontext; FvwmWindow *fw; int FinishEvent; fw = ret_ecc->w.fw; w = ret_ecc->w.w; original_w = w; wcontext = ret_ecc->w.wcontext; FinishEvent = ((fw != NULL) ? ButtonRelease : ButtonPress); if (wcontext == C_UNMANAGED && do_allow_unmanaged) { return False; } if (wcontext != C_ROOT && wcontext != C_NO_CONTEXT && fw != NULL && wcontext != C_EWMH_DESKTOP) { if (FinishEvent == ButtonPress || (FinishEvent == ButtonRelease && trigger_evtype != ButtonPress)) { return False; } else if (FinishEvent == ButtonRelease) { /* We are only waiting until the user releases the * button. Do not change the cursor. */ cursor = CRS_NONE; just_waiting_for_finish = 1; } } if (Scr.flags.are_functions_silent) { return True; } if (!GrabEm(cursor, GRAB_NORMAL)) { XBell(dpy, 0); return True; } MyXGrabKeyboard(dpy); while (!finished) { done = 0; /* block until there is an event */ FMaskEvent( dpy, ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyPressMask | VisibilityChangeMask | ButtonMotionMask | PointerMotionMask /* | EnterWindowMask | LeaveWindowMask*/, &e); if (e.type == KeyPress) { KeySym keysym = XLookupKeysym(&e.xkey, 0); if (keysym == XK_Escape) { ret_ecc->x.etrigger = &e; *ret_mask |= ECC_ETRIGGER; UngrabEm(GRAB_NORMAL); MyXUngrabKeyboard(dpy); return True; } Keyboard_shortcuts(&e, NULL, NULL, NULL, FinishEvent); } if (e.type == FinishEvent) { finished = 1; } switch (e.type) { case KeyPress: case ButtonPress: if (e.type != FinishEvent) { original_w = e.xany.window; } done = 1; break; case ButtonRelease: done = 1; break; default: break; } if (!done) { dispatch_event(&e); } } MyXUngrabKeyboard(dpy); UngrabEm(GRAB_NORMAL); if (just_waiting_for_finish) { return False; } w = e.xany.window; ret_ecc->x.etrigger = &e; *ret_mask |= ECC_ETRIGGER | ECC_W | ECC_WCONTEXT; if ((w == Scr.Root || w == Scr.NoFocusWin) && e.xbutton.subwindow != None) { w = e.xbutton.subwindow; e.xany.window = w; } if (w == Scr.Root || IS_EWMH_DESKTOP(w)) { ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } *ret_mask |= ECC_FW; if (XFindContext(dpy, w, FvwmContext, (caddr_t *)&fw) == XCNOENT) { ret_ecc->w.fw = NULL; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return (True); } if (w == FW_W_PARENT(fw)) { w = FW_W(fw); } if (original_w == FW_W_PARENT(fw)) { original_w = FW_W(fw); } /* this ugly mess attempts to ensure that the release and press * are in the same window. */ if (w != original_w && original_w != Scr.Root && original_w != None && original_w != Scr.NoFocusWin && !IS_EWMH_DESKTOP(original_w)) { if (w != FW_W_FRAME(fw) || original_w != FW_W(fw)) { ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } } if (IS_EWMH_DESKTOP(FW_W(fw))) { ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; XBell(dpy, 0); return True; } wcontext = GetContext(NULL, fw, &e, &dummy); ret_ecc->w.fw = fw; ret_ecc->w.w = w; ret_ecc->w.wcontext = C_ROOT; return False; }