📄 tkfocus.c
字号:
* * Side effects: * None. * *---------------------------------------------------------------------- */TkWindow *TkGetFocusWin(winPtr) TkWindow *winPtr; /* Window that selects an application * and a display. */{ DisplayFocusInfo *displayFocusPtr; if (winPtr == NULL) { return (TkWindow *) NULL; } displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); return displayFocusPtr->focusWinPtr;}/* *---------------------------------------------------------------------- * * TkFocusKeyEvent -- * * Given a window and a key press or release event that arrived for * the window, use information about the keyboard focus to compute * which window should really get the event. In addition, update * the event to refer to its new window. * * Results: * The return value is a pointer to the window that has the input * focus in winPtr's application, or NULL if winPtr's application * doesn't have the input focus. If a non-NULL value is returned, * eventPtr will be updated to refer properly to the focus window. * * Side effects: * None. * *---------------------------------------------------------------------- */TkWindow *TkFocusKeyEvent(winPtr, eventPtr) TkWindow *winPtr; /* Window that selects an application * and a display. */ XEvent *eventPtr; /* X event to redirect (should be KeyPress * or KeyRelease). */{ DisplayFocusInfo *displayFocusPtr; TkWindow *focusWinPtr; int focusX, focusY, vRootX, vRootY, vRootWidth, vRootHeight; displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); focusWinPtr = displayFocusPtr->focusWinPtr; /* * The code below is a debugging aid to make sure that dispPtr->focusPtr * is kept properly in sync with the "truth", which is the value in * displayFocusPtr->focusWinPtr. */#ifdef TCL_MEM_DEBUG if (focusWinPtr != winPtr->dispPtr->focusPtr) { printf("TkFocusKeyEvent found dispPtr->focusPtr out of sync:\n"); printf("expected %s, got %s\n", (focusWinPtr != NULL) ? focusWinPtr->pathName : "??", (winPtr->dispPtr->focusPtr != NULL) ? winPtr->dispPtr->focusPtr->pathName : "??"); }#endif if ((focusWinPtr != NULL) && (focusWinPtr->mainPtr == winPtr->mainPtr)) { /* * Map the x and y coordinates to make sense in the context of * the focus window, if possible (make both -1 if the map-from * and map-to windows don't share the same screen). */ if ((focusWinPtr->display != winPtr->display) || (focusWinPtr->screenNum != winPtr->screenNum)) { eventPtr->xkey.x = -1; eventPtr->xkey.y = -1; } else { Tk_GetVRootGeometry((Tk_Window) focusWinPtr, &vRootX, &vRootY, &vRootWidth, &vRootHeight); Tk_GetRootCoords((Tk_Window) focusWinPtr, &focusX, &focusY); eventPtr->xkey.x = eventPtr->xkey.x_root - vRootX - focusX; eventPtr->xkey.y = eventPtr->xkey.y_root - vRootY - focusY; } eventPtr->xkey.window = focusWinPtr->window; return focusWinPtr; } /* * The event doesn't belong to us. Perhaps, due to embedding, it * really belongs to someone else. Give the embedding code a chance * to redirect the event. */ TkpRedirectKeyEvent(winPtr, eventPtr); return (TkWindow *) NULL;}/* *---------------------------------------------------------------------- * * TkFocusDeadWindow -- * * This procedure is invoked when it is determined that * a window is dead. It cleans up focus-related information * about the window. * * Results: * None. * * Side effects: * Various things get cleaned up and recycled. * *---------------------------------------------------------------------- */voidTkFocusDeadWindow(winPtr) register TkWindow *winPtr; /* Information about the window * that is being deleted. */{ ToplevelFocusInfo *tlFocusPtr, *prevPtr; DisplayFocusInfo *displayFocusPtr; TkDisplay *dispPtr = winPtr->dispPtr; /* * Search for focus records that refer to this window either as * the top-level window or the current focus window. */ displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); for (prevPtr = NULL, tlFocusPtr = winPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL; prevPtr = tlFocusPtr, tlFocusPtr = tlFocusPtr->nextPtr) { if (winPtr == tlFocusPtr->topLevelPtr) { /* * The top-level window is the one being deleted: free * the focus record and release the focus back to PointerRoot * if we acquired it implicitly. */ if (dispPtr->implicitWinPtr == winPtr) { if (tclFocusDebug) { printf("releasing focus to root after %s died\n", tlFocusPtr->topLevelPtr->pathName); } dispPtr->implicitWinPtr = NULL; displayFocusPtr->focusWinPtr = NULL; dispPtr->focusPtr = NULL; } if (displayFocusPtr->focusWinPtr == tlFocusPtr->focusWinPtr) { displayFocusPtr->focusWinPtr = NULL; dispPtr->focusPtr = NULL; } if (prevPtr == NULL) { winPtr->mainPtr->tlFocusPtr = tlFocusPtr->nextPtr; } else { prevPtr->nextPtr = tlFocusPtr->nextPtr; } ckfree((char *) tlFocusPtr); break; } else if (winPtr == tlFocusPtr->focusWinPtr) { /* * The deleted window had the focus for its top-level: * move the focus to the top-level itself. */ tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr; if ((displayFocusPtr->focusWinPtr == winPtr) && !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) { if (tclFocusDebug) { printf("forwarding focus to %s after %s died\n", tlFocusPtr->topLevelPtr->pathName, winPtr->pathName); } GenerateFocusEvents(displayFocusPtr->focusWinPtr, tlFocusPtr->topLevelPtr); displayFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr; dispPtr->focusPtr = tlFocusPtr->topLevelPtr; } break; } } if (displayFocusPtr->focusOnMapPtr == winPtr) { displayFocusPtr->focusOnMapPtr = NULL; }}/* *---------------------------------------------------------------------- * * GenerateFocusEvents -- * * This procedure is called to create FocusIn and FocusOut events to * move the input focus from one window to another. * * Results: * None. * * Side effects: * FocusIn and FocusOut events are generated. * *---------------------------------------------------------------------- */static voidGenerateFocusEvents(sourcePtr, destPtr) TkWindow *sourcePtr; /* Window that used to have the focus (may * be NULL). */ TkWindow *destPtr; /* New window to have the focus (may be * NULL). */{ XEvent event; TkWindow *winPtr; winPtr = sourcePtr; if (winPtr == NULL) { winPtr = destPtr; if (winPtr == NULL) { return; } } event.xfocus.serial = LastKnownRequestProcessed(winPtr->display); event.xfocus.send_event = GENERATED_EVENT_MAGIC; event.xfocus.display = winPtr->display; event.xfocus.mode = NotifyNormal; TkInOutEvents(&event, sourcePtr, destPtr, FocusOut, FocusIn, TCL_QUEUE_MARK);}/* *---------------------------------------------------------------------- * * FocusMapProc -- * * This procedure is called as an event handler for VisibilityNotify * events, if a window receives the focus at a time when its * toplevel isn't mapped. The procedure is needed because X * won't allow the focus to be set to an unmapped window; we * detect when the toplevel is mapped and set the focus to it then. * * Results: * None. * * Side effects: * If this is a map event, the focus gets set to the toplevel * given by clientData. * *---------------------------------------------------------------------- */static voidFocusMapProc(clientData, eventPtr) ClientData clientData; /* Toplevel window. */ XEvent *eventPtr; /* Information about event. */{ TkWindow *winPtr = (TkWindow *) clientData; DisplayFocusInfo *displayFocusPtr; if (eventPtr->type == VisibilityNotify) { displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); if (tclFocusDebug) { printf("auto-focussing on %s, force %d\n", winPtr->pathName, displayFocusPtr->forceFocus); } Tk_DeleteEventHandler((Tk_Window) winPtr, VisibilityChangeMask, FocusMapProc, clientData); displayFocusPtr->focusOnMapPtr = NULL; SetFocus(winPtr, displayFocusPtr->forceFocus); }}/* *---------------------------------------------------------------------- * * FindDisplayFocusInfo -- * * Given an application and a display, this procedure locate the * focus record for that combination. If no such record exists, * it creates a new record and initializes it. * * Results: * The return value is a pointer to the record. * * Side effects: * A new record will be allocated if there wasn't one already. * *---------------------------------------------------------------------- */static DisplayFocusInfo *FindDisplayFocusInfo(mainPtr, dispPtr) TkMainInfo *mainPtr; /* Record that identifies a particular * application. */ TkDisplay *dispPtr; /* Display whose focus information is * needed. */{ DisplayFocusInfo *displayFocusPtr; for (displayFocusPtr = mainPtr->displayFocusPtr; displayFocusPtr != NULL; displayFocusPtr = displayFocusPtr->nextPtr) { if (displayFocusPtr->dispPtr == dispPtr) { return displayFocusPtr; } } /* * The record doesn't exist yet. Make a new one. */ displayFocusPtr = (DisplayFocusInfo *) ckalloc(sizeof(DisplayFocusInfo)); displayFocusPtr->dispPtr = dispPtr; displayFocusPtr->focusWinPtr = NULL; displayFocusPtr->focusOnMapPtr = NULL; displayFocusPtr->forceFocus = 0; displayFocusPtr->focusSerial = 0; displayFocusPtr->nextPtr = mainPtr->displayFocusPtr; mainPtr->displayFocusPtr = displayFocusPtr; return displayFocusPtr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -