Window API¶
To use:
import xp
The window API provides a high-level abstraction for drawing with UI interaction.
Windows are created with createWindowEx(), and have access to X-Plane 11 windowing
features, like support for new positioning modes (setWindowPositioningMode())
including being “popped out” into their own first-class
window in the operating system. They can also optionally be decorated in the style of X-Plane 11 windows
(like the map). (The pre X-Plane 11.50 function XPLMCreateWindow is deprecated.)
Windows operate in “boxel” units. A boxel (“box of pixels”) is a unit of virtual pixels which, depending on X-Plane’s scaling, may correspond to an arbitrary NxN “box” of real pixels on screen. Because X-Plane handles this scaling automatically, you can effectively treat the units as though you where simply drawing in pixels, and know that when X-Plane is running with 150% or 200% scaling, your drawing will be automatically scaled (and likewise all mouse coordinates, screen bounds, etc. will also be auto-scaled).
Modern windows are not constrained to the main window, they have their origin in the lower left of the entire global desktop space, and the lower left of the main X-Plane window is not guaranteed to be (0, 0). X increases as you move right, and Y increases as you move up.
Note that this requires dealing with your window’s bounds in “global desktop” positioning
units, rather than the traditional panel coordinate system. In global desktop coordinates,
the main X-Plane window may not have its origin at coordinate (0, 0), and your own window
may have negative coordinates. Assuming you don’t implicitly assume (0, 0) as your origin,
the only API change you should need is to start using getMouseLocationGlobal() rather
than (deprecated) XPLMGetMouseLocation(), and getScreenBoundsGlobal() instead
of (deprecated) XPLMGetScreenSize().
For more information and examples on window positioning, and determining monitor bounds, see More about Window Positioning.
Note: There is no API or callback for window close: When the user closes your window, you’ll simply not get any more draw callbacks.
In addition to the basic functions createWindowEx() and destroyWindow(), functions include:
Obtain and manipulate window geometry:
Change window visibility and keyboard focus:
Change window resize and positioning:
Change window attributes:
Window Drawing Functions¶
- createWindowEx(left=100, top=200, right=200, bottom=100, visible=0, draw=None, click=None, key=None, cursor=None, wheel=None, refCon=None, decoration=WindowDecorationRoundRectangle, layer=WindowLayerFloatingWindows, rightClick=None)¶
Create a new “modern” window.
- Parameters
left (int) – Left edge of window in boxels (default: 100)
top (int) – Top edge of window in boxels (default: 200)
right (int) – Right edge of window in boxels (default: 200)
bottom (int) – Bottom edge of window in boxels (default: 100)
visible (int) – 1 for visible, 0 for hidden (default: 0)
draw (Optional[Callable[[
XPLMWindowID, Any], None]]) – Draw callback function (default: None)click (Optional[Callable[[
XPLMWindowID, int, int, int, Any], int]]) – Left-click callback function (default: None)key (Optional[Callable[[
XPLMWindowID, int, int, int, Any, int], None]]) – Keyboard callback function (default: None)cursor (Optional[Callable[[
XPLMWindowID, int, int, Any], int]]) – Cursor callback function (default: None)wheel (Optional[Callable[[
XPLMWindowID, int, int, int, int, Any], int]]) – Mouse wheel callback function (default: None)refCon (Any) – Reference constant passed to callbacks (default: None)
decoration (int) – Window decoration style (default: WindowDecorationRoundRectangle)
layer (int) – Window layer (default: WindowLayerFloatingWindows)
rightClick (Optional[Callable[[
XPLMWindowID, int, int, int, Any], int]]) – Right-click callback function (default: None)
- Returns
WindowID for the created window
- Return type
Window style is indicated by decoration, and can only be specified at creation time. By default, window is created as
WindowDecorationRoundRectangleand looks like:
decoration must be one of:
Decoration Value
Meaning
- WindowDecorationNone = 0¶
X-Plane will draw no decoration for your window, and apply no automatic click handlers. The window will not stop click from passing through its bounds. This is suitable for “windows” which request, say, the full screen bounds, then only draw in a small portion of the available area.
Official SDK xplm_WindowDecorationNone
- WindowDecorationRoundRectangle = 1¶
The default decoration for “native” windows, like the map. Provides a solid background, as well as click handlers for resizing and dragging the window.
Official SDK xplm_WindowDecorationRoundRectangle
- WindowDecorationSelfDecorated = 2¶
X-Plane will draw no decoration for your window, nor will it provide resize handlers for your window edges, but it will stop clicks from passing through your windows bounds.
Official SDK xplm_WindowDecorationSelfDecorated
- WindowDecorationSelfDecoratedResizable = 3¶
Like self-decorated, but with resizing; X-Plane will draw no decoration for your window, but it will stop clicks from passing through your windows bounds, and provide automatic mouse handlers for resizing.
Official SDK xplm_WindowDecorationNone
layer describes where in the ordering of windows X-Plane should place this window. Windows in higher layers cover windows in lower layers. So, a given window might be at the top of its particular layer, but it might still be obscured by a window in a higher layer. (This happens frequently when floating windows, like X-Plane’s map, are covered by a modal alert.) Layer is specified only at creation time, and is one of:
XPLMWindowLayer
Layer Value
Meaning
- WindowLayerFlightOverlay = 0¶
The lowest layer, used for HUD-like displays while flying.
Official SDK xplm_WindowLayerFlightOverlay
- WindowLayerFloatingWindows = 1¶
Windows that “float” over the sim, like the X-Plane 11 map does. If you are not sure which layer to create your window in, choose floating
Official SDK xplm_WindowLayerFloatingWindows
- WindowLayerModal = 2¶
An interruptive modal that covers the sim with a transparent black overlay to draw the user’s focus to the alert.
Official SDK xplm_WindowLayerModal
- WindowLayerGrowlNotifications = 3¶
“Growl”-style notifications that are visible in a corder of the screen, even over modals.
Official SDK xplm_WindowLayerGrowlNotifications
>>> windowID = xp.createWindowEx(visible=1)
There are six possible callback functions to be provided.
Callback function signature
Returns
draw(windowID, refCon)
No return
key(windowID, key, flags, vKey, refCon, losingFocus)
No return
cursor(windowID, x, y, refCon)
cursorStatus
click(windowID, x, y, mouseStatus, refCon)
1 =Consume click
0 =Pass it through
wheel(windowID, x, y, wheel, clicks, refCon)
1 =Consume click
0 =Pass it through
rightClick(windowID, x, y, mouseStatus, refCon)
1 =Consume click
0 =Pass it through
For legacy purposes, you may pass a 14-element tuple instead of individually specifying the parameters.
The tuple is:
( left, top, right, bottom, visible, draw, click, key, cursor, wheel, refCon, decoration, layer, rightClick )
Note the order is very important!
You pass in a tuple with all of the fields set in.
>>> t = (100, 200, 200, 100, 1, ... None, None, None, None, None, ... None, ... xp.WindowDecorationRoundRectangle, xp.WindowLayerFloatingWindows, ... None) ... >>> windowID = xp.createWindowEx(t)
Official SDK XPLMCreateWindowEx
- destroyWindow(windowID)¶
Destroys a window based on the handle passed in.
- Parameters
windowID (
XPLMWindowID) – Window to be destroyed- Returns
None
The callbacks are not called after this call. Keyboard focus is removed from the window before destroying it.
Official SDK XPLMDestroyWindow
Window Drawing Callbacks¶
These are the callbacks you’ll provide and pass into createWindowEx() when creating
the window, or using the tuple.
- draw(windowID, refCon)¶
Window drawing callback prototype.
- Parameters
windowID – window to be drawn
refCon – refCon you provided on creation
- Returns
No return value
This function handles drawing. You are passed in your windowID and its refCon. Draw the window. You can use
getWindowGeometry()to find its current dimensions. When this callback is called, the OpenGL context will be set properly for cockpit drawing. NOTE: Because you are drawing your window over a background, you can make a transparent window easily by simply not filling in your entire window’s bounds.>>> def MyDraw(windowID, refCon): ... (left, top, right, bottom) = xp.getWindowGeometry(windowID) ... xp.drawString([1, 0, 0], left + 10, top - 10, refCon, None, xp.Font_Basic) ... >>> phrase = "Hello" >>> windowID = xp.createWindowEx(visible=1, draw=MyDraw, refCon=phrase) >>> >>> xp.destroyWindow(windowID)
- click(windowID, x, y, mouseStatus, refCon)¶
- rightClick(windowID, x, y, mouseStatus, refCon)¶
Mouse handling callback prototype. Same signature for Left-clicks and Right-clicks. (Note if you do use the same callback for both right and left clicks, you cannot determine from the parameters if you are being called due to a right or left click. For this reason, you might want to use two different functions.)
- Parameters
windowID – window receiving the mouse click
x – horizontal position of mouse
y – vertical position of mouse
mouseStatus – flag, see table below.
refCon – refCon you provided on creation
- Returns
1= consume the click, or 0= to pass it through.
You receive this call when the mouse button is pressed down or released. Between then these two calls is a drag. You receive the x and y of the click, your window, and a refcon. Return 1 to consume the click, or 0 to pass it through.
Warning
passing clicks through windows (as of this writing) causes mouse tracking problems in X-Plane; do not use this feature!
When the mouse is clicked, your mouse click routine is called repeatedly. It is first called with the mouse down message. It is then called zero or more times with the mouse-drag message, and finally it is called once with the mouse up message. All of these messages will be directed to the same window.
>>> def MyDraw(windowID, refCon): ... if refCon: ... (left, top, right, bottom) = xp.getWindowGeometry(windowID) ... xp.drawString([1, 0, 0], left + 10, top - 10, refCon, None, xp.Font_Basic) ... >>> def MyClick(windowID, x, y, mouseStatus, refCon): ... status = "Down" if mouseStatus == xp.MouseDown else "Up" if mouseStatus == xp.MouseUp else "Drag" ... xp.setWindowRefCon(windowID, f"({x}, {y}): {status}") ... return 1 # Remember to return a value!! ... >>> windowID = xp.createWindowEx(visible=1, click=MyClick, draw=MyDraw) >>> >>> xp.destroyWindow(windowID)
Mouse Status Value
SDK Value
xplm_MouseDown
xplm_MouseDrag
xplm_MouseUp
Note
It appears only MouseDown is ever sent: You will never receive MouseDrag or MouseUp events. Also, be aware that edges of popups are reserved for X-Plane window manipulation (i.e., resize and move) and you will not receive events near the edges. This includes what might be considered the “title bar”, the 25 pixels or so at the top of the popup window.
- key(windowID, key, flags, vKey, refCon, losingFocus)¶
Window keyboard input handling callback prototype.
- Parameters
windowID – window receiving the key press or focus
key – Key pressed
flags – OR’d values for Shift / Ctrl, etc. See table below
vKey – Virtual key code (Virtual Key Codes)
refCon – refCon you provided on creation
losingFocus – 1= your window is losing keyboard focus (and key should be ignored)
- Returns
No return value
This function is called when a key is pressed or keyboard focus is taken away from your window. If losingFocus is 1, you are losing the keyboard focus, otherwise a key was pressed and key contains its character.
>>> def MyDraw(windowID, refCon): ... if refCon: ... (left, top, right, bottom) = xp.getWindowGeometry(windowID) ... xp.drawString([1, 0, 0], left + 10, top - 10, refCon, None, xp.Font_Basic) ... >>> def MyKey(windowID, key, flags, vKey, refCon, losingFocus): ... if losingFocus: ... status = "Lost Focus" ... elif flags & xp.DownFlag: ... status = ['Key Down', ] ... if flags & xp.ShiftFlag: ... status.append("Shift") ... if flags & xp.OptionAltFlag: ... status.append("Option") ... if flags & xp.ControlFlag: ... status.append("Control") ... status.append(xp.getVirtualKeyDescription(vKey)) ... status = ' '.join(status) ... elif flags & xp.UpFlag: ... status = "Key Up" ... else: ... return 1 # status unchanged ... xp.setWindowRefCon(windowID, status) ... return 1 # Remember to return a value!! ... >>> windowID = xp.createWindowEx(visible=1, key=MyKey, draw=MyDraw) >>> xp.takeKeyboardFocus(windowID) # (because the debugger has focus right now) >>> >>> xp.destroyWindow(windowID)
Key Flags Value
SDK Value
ShiftFlag
xplm_ShiftFlag
OptionAltFlag
xplm_OptionAltFlag
ControlFlag
xplm_ControlFlag
DownFlag
xplm_DownFlag
UpFlag
xplm_UpFlag
Warning
X-Plane sends the wrong windowID when losingFocus is set. We’re supposed to get the windowID of the losing window, instead we get the windowID of the window gaining focus. The problem is, we cannot determine which window is actually losing focus & therefore cannot forward this “losing” message to the correct window’s
key()callback function. Bug filed with Laminar 22-October-2021. As this will require a re-work of the X-Plane API to actually fix it, there is no time line on this.As a result, you will never receive a callback with
losingFocus=1.
- cursor(windowID, x, y, refCon)¶
Mouse cursor handling callback prototype.
- Parameters
windowID – window receiving the notice
x – horizontal position of mouse
y – vertical position of mouse
refCon – refCon you provided on creation
- Returns
Cursor status (see below)
The SDK calls your cursor status callback when the mouse is over your plugin window. Return a cursor status code to indicate how you would like X-Plane to manage the cursor. If you return
CursorDefault, the SDK will try lower-Z-order plugin windows, then let the sim manage the cursor.Note
you should never show or hide the cursor yourself using non-X-Plane routines as these APIs are typically reference-counted and thus cannot safely and predictably be used by the SDK. Instead return one of
CursorHiddento hide the cursor orCursorArrow/CursorCustomto show the cursor.>>> def MyCursor(windowID, x, y, refCon): ... (left, top, right, bottom) = xp.getWindowGeometry(windowID) ... # Arrow, if on the left half of window, Hide if on the right ... if x > left and x < (right + left) / 2: ... return xp.CursorArrow ... else: ... return xp.CursorHidden ... >>> windowID = xp.createWindowEx(visible=1, cursor=MyCursor) >>> >>> xp.destroyWindow(windowID)
If you want to implement a custom cursor by drawing a cursor in OpenGL, use
CursorHiddento hide the OS cursor and draw the cursor using a 2-d drawing callback (afterPhase_Windowis probably a good choice).If you want to use a custom OS-based cursor, return
CursorCustomto ask X-Plane to show the cursor but not affect its image. You can then usexp.setCursor()to display a custom cursor you’ve loaded. (Seexp.setCursor()for detailed example.)XPLMCursorStatus¶
Cursor Status Value
SDK Value
- CursorDefault = 0¶
X-Plane manages the cursor normally, plugins does not affect the cursor.
Official SDK xplm_CursorDefault
- CursorHidden = 1¶
X-Plane hides the cursor.
Official SDK xplm_CursorHidden
- CursorArrow = 2¶
X-Plane shows the cursor as the default arrow.
Official SDK xplm_CursorArrow
- CursorCustom = 3¶
X-Plane shows the cursor but lets you select an OS cursor. See XPCursor.
Official SDK xplm_CursorCustom
- CursorRotateSmall = 4¶
X-Plane shows the small left-right rotation cursor.
Official SDK xplm_CursorRotateSmall
- CursorRotateSmallLeft = 5¶
X-Plane shows the small left rotation cursor.
Official SDK xplm_CursorRotateSmallLeft
- CursorRotateSmallRight = 6¶
X-Plane shows the small right rotation cursor.
Official SDK xplm_CursorRotateSmallRight
- CursorRotateMedium = 7¶
X-Plane shows the medium left-right rotation cursor.
Official SDK xplm_CursorRotateMedium
- CursorRotateMediumLeft = 8¶
X-Plane shows the medium left rotation cursor.
Official SDK xplm_CursorRotateMediumLeft
- CursorRotateMediumRight = 9¶
X-Plane shows the medium right rotation cursor.
Official SDK xplm_CursorRotateMediumRight
- CursorRotateLarge = 10¶
X-Plane shows the large left-right rotation cursor.
Official SDK xplm_CursorRotateLarge
- CursorRotateLargeLeft = 11¶
X-Plane shows the large left rotation cursor.
Official SDK xplm_CursorRotateLargeLeft
- CursorRotateLargeRight = 12¶
X-Plane shows the large right rotation cursor.
Official SDK xplm_CursorRotateLargeRight
- CursorUpDown = 13¶
X-Plane shows the up-down arrow cursor.
Official SDK xplm_CursorUpDown
- CursorDown = 14¶
X-Plane shows the down arrow cursor.
Official SDK xplm_CursorDown
- CursorUp = 15¶
X-Plane shows the up arrow cursor.
Official SDK xplm_CursorUp
- CursorLeftRight = 16¶
X-Plane shows the left-right arrow cursor.
Official SDK xplm_CursorLeftRight
- CursorLeft = 17¶
X-Plane shows the left arrow cursor.
Official SDK xplm_CursorLeft
- CursorRight = 18¶
X-Plane shows the right arrow cursor.
Official SDK xplm_CursorRight
- CursorButton = 19¶
X-Plane shows the button-pushing cursor.
Official SDK xplm_CursorButton
- CursorHandle = 20¶
X-Plane shows the handle-grabbing cursor.
Official SDK xplm_CursorHandle
- CursorFourArrows = 21¶
X-Plane shows the four-arrows cursor.
Official SDK xplm_CursorFourArrows
- CursorSplitterH = 22¶
X-Plane shows the cursor to drag a horizontal splitter bar.
Official SDK xplm_CursorSplitterH
- CursorSplitterV = 23¶
X-Plane shows the cursor to drag a vertical splitter bar.
Official SDK xplm_CursorSplitterV
- CursorText = 24¶
X-Plane shows the I-Beam cursor for text editing.
Official SDK xplm_CursorText
- wheel(windowID, x, y, wheel, clicks, refCon)¶
Mouse wheel handling callback prototype.
- Parameters
windowID – window receiving the mouse event
x – horizontal position of mouse
y – vertical position of mouse
wheel – 0= vertical axis, 1= horizontal axis
clicks – number of “clicks” indicating how far the wheel has turned since previous callback
refCon – refCon you provided on creation
- Returns
1= consume the mouse wheel click, 0= pass to lower window
The SDK calls your mouse wheel callback when one of the mouse wheels is turned within your window. Return 1 to consume the mouse wheel clicks or 0 to pass them on to a lower window. (You should consume mouse wheel clicks even if they do nothing, if your window appears opaque to the user.) The number of clicks indicates how far the wheel was turned since the last callback. The wheel is 0 for the vertical axis or 1 for the horizontal axis (for OS/mouse combinations that support this).
The units for x and y values matches the units used in your window (i.e., boxels), with origin in lower left of global desktop space.
Screen and Monitor Functions¶
See detailed explanation of screens vs. monitors and positioning windows within bounds in More about Window Positioning.
- getScreenSize()¶
Query X-Plane screen size.
- Returns
Tuple of (width, height) in pixels
- Return type
tuple[int, int]
This routine returns the size of the size of the X-Plane OpenGL window in pixels. Please note that this is not the size of the screen when doing 2-d drawing (the 2-d screen is currently always 1024x768, and graphics are scaled up by OpenGL when doing 2-d drawing for higher-res monitors). This number can be used to get a rough idea of the amount of detail the user will be able to see when drawing in 3-d.
>>> xp.getScreenSize() (1280, 1024)
Official SDK XPLMGetScreenSize
- getScreenBoundsGlobal()¶
This routine returns the bounds of the “global” X-Plane desktop, in boxels.
- Returns
Tuple of (left, top, right, bottom) in boxels
- Return type
tuple[int, int, int, int]
Unlike the non-global version
getScreenSize(), this is multi-monitor aware. There are three primary consequences of multimonitor awareness:First, if the user is running X-Plane in full-screen on two or more monitors (typically configured using one full-screen window per monitor), the global desktop will be sized to include all X-Plane windows.
Second, the origin of the screen coordinates is not guaranteed to be (0, 0). Suppose the user has two displays side- by-side, both running at 1080p. Suppose further that they’ve configured their OS to make the left display their “primary” monitor, and that X-Plane is running in full-screen on their right monitor only. In this case, the global desktop bounds would be the rectangle from (1920, 0) to (3840, 1080). If the user later asked X-Plane to draw on their primary monitor as well, the bounds would change to (0, 0) to (3840, 1080).
Finally, if the usable area of the virtual desktop is not a perfect rectangle (for instance, because the monitors have different resolutions or because one monitor is configured in the operating system to be above and to the right of the other), the global desktop will include any wasted space. Thus, if you have two 1080p monitors, and monitor 2 is configured to have its bottom left touch monitor 1’s upper right, your global desktop area would be the rectangle from (0, 0) to (3840, 2160).
If the X-Plane is running in a window (i.e., not full screen), the values returned are the size of the within in boxels (
getScreenSize()returns pixels) with the (0, 0) origin in the bottom left corner.Note that popped-out windows (windows drawn in their own operating system windows, rather than “floating” within X-Plane) are not included in these bounds.
Return (left, top, right, bottom)
>>> xp.getScreenBoundsGlobal() (-1280, 1440, 2560, 0)
Official SDK XPLMGetScreenBoundsGlobal
- getAllMonitorBoundsGlobal(bounds, refCon)¶
This routine immediately calls your bounds() function the bounds (in boxels) of each full-screen X-Plane window within the X- Plane global desktop space.
- Parameters
bounds (Callable[[int, int, int, int, int, Any], None]) – Callback function to receive monitor bounds
refCon (Any) – Reference constant passed to callback
- Returns
None
Note that if a monitor is not covered by an X-Plane window, you cannot get its bounds this way. Likewise, monitors with only an X-Plane window (not in full-screen mode) will not be included.
If X-Plane is running in full-screen and your monitors are of the same size and configured contiguously in the OS, then the combined global bounds of all full-screen monitors will match the total global desktop bounds, as returned by
getScreenBoundsGlobal(). (Of course, if X-Plane is running in windowed mode, this will not be the case. Likewise, if you have differently sized monitors, the global desktop space will include wasted space.)Note that this function’s monitor indices match those provided by
getAllMonitorBoundsOS(), but the coordinates are different (since the X-Plane global desktop may not match the operating system’s global desktop, and one X-Plane boxel may be larger than one pixel due to 150% or 200% scaling).>>> def MyBounds(index, left, top, right, bottom, refCon): ... refCon[index] = (left, top, right, bottom) ... >>> data = {} >>> xp.getAllMonitorBoundsGlobal(MyBounds, data) >>> data {0: (0, 1440, 2560, 0), 2: (-1280, 1368, 0 344)}
(In the above example, I have two of my three monitors running fullscreen.)
This function is informed of the global bounds (in boxels) of a particular monitor within the X-Plane global desktop space. Note that X-Plane must be running in full screen on a monitor in order for that monitor to be passed to you in this callback. If it is not running full screen, the function will set data to
{}.
- getAllMonitorBoundsOS(bounds, refCon)¶
This routine immediately calls your bounds() function with the bounds (in pixels) of each monitor within the operating system’s global desktop space.
- Parameters
bounds (Callable[[int, int, int, int, int, Any], None]) – Callback function to receive monitor bounds
refCon (Any) – Reference constant passed to callback
- Returns
None
Note that unlike
getAllMonitorBoundsGlobal(), this may include monitors that have no X-Plane window on them.Note that this function’s monitor indices match those provided by
getAllMonitorBoundsGlobal(), but the coordinates are different (since the X-Plane global desktop may not match the operating system’s global desktop, and one X-Plane boxel may be larger than one pixel).>>> def MyBoundsOS(index, left, top, right, bottom, refCon): ... refCon[index] = (left, top, right, bottom) ... >>> data = {} >>> xp.getAllMonitorBoundsOS(MyBoundsOS, data) >>> data {0: (0, 1440, 2560, 0), 1: (2560, 1840, 3760, -80), 2: (-1280, 1368, 0, 344)}
This function is informed of the global bounds (in pixels) of a particular monitor within the operating system’s global desktop space. Note that a monitor index being passed to you here does not indicate that X-Plane is running in full screen on this monitor, or even that any X-Plane windows exist on this monitor. (So this will work regardless of whether X-Plane is running full-screen or windowed.
Official SDK XPLMGetAllMonitorBoundsOS
- getMouseLocationGlobal()¶
Returns the current mouse location in global desktop boxels.
- Returns
Tuple of (x, y) in boxels
- Return type
tuple[int, int]
Unlike older
getMouseLocation(), the bottom left of the main X-Plane window is not guaranteed to be (0, 0). Instead, the origin is the lower left of the entire global desktop space. In addition, this routine gives the real mouse location when the mouse goes to X-Plane windows other than the primary display. Thus, it can be used with both pop-out windows and secondary monitors.For windowed (not full-screen) simulator, (0,0) is lower left corner of the X-Plane window, with the mouse position going negative when moved left or below the window.
This is the mouse location function to use with modern windows (i.e., those created by
createWindowEx()).Returns (x, y)
>>> xp.getMouseLocationGlobal() (3025, 204)
Official SDK XPLMGetMouseLocationGlobal
Window Functions¶
- getWindowGeometry(windowID)¶
This routine returns the position and size of a window.
- Parameters
windowID (
XPLMWindowID) – Window to query- Returns
Tuple of (left, top, right, bottom)
- Return type
tuple[int, int, int, int]
The units and coordinate system vary depending on the type of window you have.
If this is a legacy window (one compiled against a pre-XPLM300 version of the SDK, or an XPLM300 window that was not created using
createWindowEx()), the units are pixels relative to the main X-Plane display.For X-Plane 11 and 12 windows (compiled against the XPLM300 SDK and created using
createWindowEx()), the units are global desktop boxels.>>> windowID = xp.createWindowEx() >>> xp.getWindowGeometry(windowID) (100, 200, 200, 100)
Note that a window has geometry even when not visible &
createWindowEx()creates hidden windows by default. Make it visible usingxp.setWindowIsVisible(windowID).Also supports older calling style where you pass in lists as parameters, the results are copied rather than returned. (Don’t use this – it’s here really just to help those used to the way C-language SDK worked.)
>>> left = []; right = []; top = []; bottom = []; >>> xp.getWindowGeometry(windowID, left, top, right, bottom) >>> left[0] 100 >>> top[0] 200
Official SDK XPLMGetWindowGeometry
- setWindowGeometry(windowID, left, top, right, bottom)¶
Set window position and size.
- Parameters
windowID (
XPLMWindowID) – Window to modifyleft (int) – Left edge coordinate
top (int) – Top edge coordinate
right (int) – Right edge coordinate
bottom (int) – Bottom edge coordinate
- Returns
None
This routine allows you to set the position and size of a window.
The units and coordinate system match those of
getWindowGeometry(). That is, modern windows use global desktop boxel coordinates, while legacy windows use pixels relative to the main X-Plane display.Note that this only applies to “floating” windows (that is, windows that are drawn within the X-Plane simulation windows, rather than being “popped out” into their own first-class operating system windows). To set the position of windows whose positioning mode is
WindowPopOut, you’ll need to instead usesetWindowGeometryOS().>>> windowID = xp.createWindowEx() >>> xp.getWindowGeometry(windowID) (100, 200, 200, 100) >>> xp.setWindowGeometry(windowID, 200, 300, 400, 250) >>> xp.getWindowGeometry(windowID) (200, 300, 400, 250)
Official SDK XPLMSetWindowGeometry
- getWindowGeometryOS(windowID)¶
This routine returns the position and size of a “popped out” window (i.e., a window whose positioning mode is WindowPopOut), in operating system pixels.
- Parameters
windowID (
XPLMWindowID) – Window to query (must be popped out)- Returns
Tuple of (left, top, right, bottom) in OS pixels
- Return type
tuple[int, int, int, int]
If the window is not popped out, do not use.
>>> windowID = xp.createWindowEx() >>> xp.setWindowPositioningMode(windowID, xp.WindowPopOut, -1) >>> xp.getWindowGeometryOS(windowID) (90 610, 210, 490)
Also supports alternate calling style where you can pass lists as parameters (see example with
getWindowGeometry().Official SDK XPLMGetWindowGeometryOS
- setWindowGeometryOS(windowID, left, top, right, bottom)¶
This routine allows you to set the position and size, in operating system pixel coordinates, of a popped out window.
- Parameters
windowID (
XPLMWindowID) – Window to modify (must be popped out)left (int) – Left edge in OS pixels
top (int) – Top edge in OS pixels
right (int) – Right edge in OS pixels
bottom (int) – Bottom edge in OS pixels
- Returns
None
The window must have positioning mode
WindowPopOut, which exists outside the X-Plane simulation window, in its own first-class operating system window.Note that you are responsible for ensuring both that your window is popped out (using
windowIsPoppedOut()) and that a monitor really exists at the OS coordinates you provide (usinggetAllMonitorBoundsOS()).Official SDK XPLMSetWindowGeometryOS
- getWindowGeometryVR(windowID)¶
Returns the width and height, in boxels, of a window in VR.
- Parameters
windowID (
XPLMWindowID) – Window to query (must be in VR)- Returns
Tuple of (widthBoxels, heightBoxels)
- Return type
tuple[int, int]
Note that you are responsible for ensuring your window is in VR (using
windowIsInVR()).>>> windowID = xp.createWindowEx() >>> if xp.windowIsInVR(windowID): ... xp.getWindowGeometryVR(windowID) ... (200, 100)
Official SDK XPLMGetWindowGeometryVR
- setWindowGeometryVR(windowID, width, height)¶
This routine allows you to set the size, in boxels, of a window in VR.
- Parameters
windowID (
XPLMWindowID) – Window to modify (must be in VR)width (int) – Width in boxels
height (int) – Height in boxels
- Returns
None
The window must have positioning mode
WindowVR.Note that you are responsible for ensuring your window is in VR (using
windowIsInVR()).Official SDK XPLMSetWindowGeometryVR
- getWindowIsVisible(windowID)¶
Get window’s isVisible attribute value.
- Parameters
windowID (
XPLMWindowID) – Window to query- Returns
1 if visible, 0 otherwise
- Return type
int
>>> windowID = xp.createWindowEx() >>> xp.getWindowIsVisible(windowID) 0
Official SDK XPLMGetWindowIsVisible
- setWindowIsVisible(windowID, visible=1)¶
Set window’s visible attribute value.
- Parameters
windowID (
XPLMWindowID) – Window to modifyvisible (int) – 1 for visible, 0 for hidden (default: 1)
- Returns
None
Official SDK XPLMSetWindowIsVisible
- windowIsPoppedOut(windowID)¶
True if this window has been popped out (making it a first-class window in the operating system).
- Parameters
windowID (
XPLMWindowID) – Window to query- Returns
1 if window is popped out, 0 otherwise
- Return type
int
This is true if and only if you have set the window’s positioning mode to
WindowPopOut.Only applies to modern windows. (Windows created using the deprecated XPLMCreateWindow(), or windows compiled against a pre-XPLM300 version of the SDK cannot be popped out.)
Official SDK XPLMWindowIsPoppedOut
- windowIsInVR(windowID)¶
True if this window has been moved to the virtual reality (VR) headset.
- Parameters
windowID (
XPLMWindowID) – Window to query- Returns
1 if window is in VR, 0 otherwise
- Return type
int
This is true if and only if you have set the window’s positioning mode to
WindowVR.Only applies to modern windows. (Windows created using the deprecated XPLMCreateWindow(), or windows compiled against a pre-XPLM301 version of the SDK cannot be moved to VR.)
Official SDK XPLMWindowIsInVR
- setWindowGravity(windowID, left, top, right, bottom)¶
A window’s “gravity” controls how the window shifts as the whole X-Plane window resizes.
- Parameters
windowID (
XPLMWindowID) – Window to modifyleft (float) – Left edge gravity (0.0 to 1.0)
top (float) – Top edge gravity (0.0 to 1.0)
right (float) – Right edge gravity (0.0 to 1.0)
bottom (float) – Bottom edge gravity (0.0 to 1.0)
- Returns
None
A gravity of 1 means the window maintains its positioning relative to the right or top edges, 0 the left/bottom, and 0.5 keeps it centered.
Default gravity is (0.0, 1.0, 0.0, 1.0), meaning your window will maintain its position relative to the top left and will not change size as its containing window grows. (That is, the right and bottom edges of your window will also maintain relative positions to top left.)
(0.0, 1.0, 0.0, 1.0)can be interpreted as:value
Refers to your…
Resulting in…
0.0
left edge of your window
“0.0” means it will maintain position relative to left of screen
1.0
top edge of your window
“1.0” means it will maintain position relative to top of screen
0.0
right edge of your window,
“0.0” means it will maintain position relative to left of screen
1.0
bottom edge of your window
“1.0” means it will maintain position relative to top of screen
Therefore your window will keep its size, and the upper left of your window will stay in the same location (i.e., same number of pixels from down from the top and over from the left of the screen.
(0.0, 1.0, 1.0, 1.0)can be interpreted as:value
Refers to your…
Resulting in…
0.0
left edge of your window
“0.0” means it will maintain position relative to left of screen
1.0
top edge of your window
“1.0” means it will maintain position relative to top of screen
1.0
right edge of your window,
“1.0” means it will maintain position 100% relative to right
1.0
bottom edge of your window
“1.0” means it will maintain position relative to top of screen
As before, this will keep upper left edges where they are, bottom remains same distance from top (so the window remains same height). However, right edge of your window will track the right side of your screen: if your screen increases 100, your window’s right edge expands 100%, or 100 pixels.
(0.0, 1.0, 0.5, 1.0)can be interpreted as:value
Refers to your…
Resulting in…
0.0
left edge of your window
“0.0” means it will maintain position relative to left of screen
1.0
top edge of your window
“1.0” means it will maintain position relative to top of screen
0.5
right edge of your window,
“0.5” means it will maintain position 50% relative to right
1.0
bottom edge of your window
“1.0” means it will maintain position relative to top of screen
Same as previous but right edge expands 50% of the change in screen width: If your screen increases 100, your window’s right edge expands 50)
Only applies to modern windows. (Windows created using the deprecated older XPLMCreateWindow(), or windows compiled against a pre-XPLM300 version of the SDK will simply get the default gravity.)
Official SDK XPLMSetWindowGravity
- setWindowResizingLimits(windowID, minWidth=0, minHeight=0, maxWidth=10000, maxHeight=10000)¶
Sets the minimum and maximum size of the client rectangle of the given window.
- Parameters
windowID (
XPLMWindowID) – Window to modifyminWidth (int) – Minimum width in boxels (default: 0)
minHeight (int) – Minimum height in boxels (default: 0)
maxWidth (int) – Maximum width in boxels (default: 10000)
maxHeight (int) – Maximum height in boxels (default: 10000)
- Returns
None
The client rectangle does not include any window styling that you might have asked X-Plane to apply on your behalf. All resizing operations are constrained to these sizes. (Except see Note below.)
Only applies to modern windows. (Windows created using the deprecated XPLMCreateWindow(), or windows compiled against a pre-XPLM300 version of the SDK will have no minimum or maximum size.)
This is especially useful if you’ve set window gravity (
setWindowGravity()such that the height or width of the window changes as the screen changes.Note
setWindowGravity()may cause the window to expand exceeding maxWidth, maxHeight values forsetWindowResizingLimits(), any future changes to that window’s geometry (either via manual dragging orsetWindowGeometry()) will cause the window to snap to its declared sizing limit, but until the window is resized, it will remain too large. Bug filed with Laminar 23-October-2021 as XPD-11455. Minimum sizes are correctly constrained.Official SDK XPLMSetWindowResizingLimits
>>> windowID = xp.createWindowEx(visible=1, left=100, right=200) >>> xp.setWindowResizingLimits(windowID, minWidth=100)
- setWindowPositioningMode(windowID, mode, index=-1)¶
Sets the policy for how X-Plane will position your window.
- Parameters
windowID (
XPLMWindowID) – Window to modifymode (int) – Positioning mode constant
index (int) – Monitor index, or -1 for main monitor (default: -1)
- Returns
None
Some positioning modes apply to a particular monitor. For those modes, you can pass a negative monitor index to position the window on the main X-Plane monitor (the screen with the X-Plane menu bar at the top). Or, if you have a specific monitor you want to position your window on, you can pass a real monitor index as received from, e.g.,
getAllMonitorBoundsOS().Only applies to modern windows. (Windows created using the deprecated XPLMCreateWindow(), or windows compiled against a pre-XPLM300 version of the SDK will always use xplm_WindowPositionFree.)
The mode describes how X-Plane will position your window on the user’s screen. X-Plane will maintain this positioning mode even as the user resizes their window or adds/removes full-screen monitors.
Official SDK XPLMSetWindowPositioningMode
>>> windowID = xp.createWindowEx(visible=1) >>> xp.setWindowPositioningMode(windowID, xp.WindowPopOut)
XPLMWindowPositioningMode
Positioning Mode Value
Meaning
- WindowPositionFree = 0¶
The default positioning mode. Set the window geometry and its future position will be determined by its window gravity, resizing limits, and user interactions.
Official SDK xplm_WindowPositionFree
- WindowCenterOnMonior = 1¶
Keep the window centered on the monitor you specify
Official SDK xplm_WindowCenterOnMonitor
- WindowFullScreenOnMonitor = 2¶
Keep the window full screen on the monitor you specify
Official SDK xplm_WindowFullScreenOnMonitor
- WindowFullScreenOnAllMonitors = 3¶
Like gui_window_full_screen_on_monitor, but stretches over all monitors and popout windows. This is an obscure one… unless you have a very good reason to need it, you probably don’t!
Official SDK xplm_WindowFullScreenOnAllMonitors
- WindowPopOut = 4¶
A first-class window in the operating system, completely separate from the X-Plane window(s)
Official SDK xplm_WindowPopOut
- WindowVR = 5¶
A floating window visible on the VR headset
Official SDK xplm_WindowVR
- setWindowTitle(windowID, title)¶
Sets the name for a window.
- Parameters
windowID (
XPLMWindowID) – Window to modifytitle (str) – New window title
- Returns
None
This only applies to windows that opted-in to styling as an X-Plane 11 floating window (i.e., with styling mode
xplm_WindowDecorationRoundRectangle) when they were created usingXPLMCreateWindowEx().>>> windowID = xp.createWindowEx(visible=1) >>> xp.setWindowTitle(windowID, "New Title")
Official SDK: XPLMSetWindowTitle
- getWindowRefCon(windowID)¶
Return window’s refCon attribute value (which you provided on window creation.)
- Parameters
windowID (
XPLMWindowID) – Window to query- Returns
Reference constant value
- Return type
Any
>>> windowID = xp.createWindowEx(visible=1) >>> xp.getWindowRefCon(windowID) None
Official SDK: XPLMGetWindowRefCon
- setWindowRefCon(windowID, refCon)¶
Set window’s refcon attribute value.
- Parameters
windowID (
XPLMWindowID) – Window to modifyrefCon (Any) – Reference constant value to store
- Returns
None
Use this to pass data to yourself in the callbacks.
>>> windowID = xp.createWindowEx(visible=1) >>> xp.getWindowRefCon(windowID) None >>> xp.setWindowRefCon(windowID, {"data": "value"}) >>> xp.getWindowRefCon(windowID, {"data": "value"}) {"data": "value"}
Official SDK: XPLMSetWindowRefCon
- takeKeyboardFocus(windowID)¶
Give a specific window keyboard focus.
- Parameters
windowID (
XPLMWindowID) – Window to receive focus, or 0 to give focus to X-Plane- Returns
None
This routine gives a specific window keyboard focus. Keystrokes will be sent to that window. Pass a window ID of 0 to remove keyboard focus from any plugin-created windows and instead pass keyboard strokes directly to X-Plane.
>>> windowID = xp.createWindowEx(visible=1) >>> xp.hasKeyboardFocus(windowID) 0 >>> xp.takeKeyboardFocus(windowID) ; xp.hasKeyboardFocus(windowID) 1
(Because the debugger will have keyboard focus, for obvious reasons, execute take and has on the same line to see the above results.)
Official SDK: XPLMTakeKeyboardFocus
- hasKeyboardFocus(windowID)¶
Returns 1 if the indicated window has keyboard focus.
- Parameters
windowID (
XPLMWindowID) – Window to query, or 0 for X-Plane focus- Returns
1 if window has focus, 0 otherwise
- Return type
int
Pass a window ID of 0 to see if no plugin window has focus, and all keystrokes will go directly to X-Plane.
Official SDK: XPLMHasKeyboardFocus
- bringWindowToFront(windowID)¶
Bring window to the front of the Z-order.
- Parameters
windowID (
XPLMWindowID) – Window to bring to front- Returns
None
This routine brings the window to the front of the Z-order for its layer. Windows are brought to the front automatically when they are created. Beyond that, you should make sure you are front before handling mouse clicks.
Note that this only brings your window to the front of its layer XPLMWindowLayer. Thus, if you have a window in the floating window layer (
WindowLayerFloatingWindows), but there is a modal window (in layerWindowLayerModal) above you, you would still not be the true frontmost window after calling this. (After all, the window layers are strictly ordered, and no window in a lower layer can ever be above any window in a higher one.) Windows are brought to the front when they are created. Beyond that you should make sure you are front before handling mouse clicks.Official SDK: XPLMBringWindowToFront
- isWindowInFront(windowID)¶
This routine returns 1 if the window you passed in is the frontmost visible window in its layer.
- Parameters
windowID (
XPLMWindowID) – Window to query- Returns
1 if window is in front of its layer, 0 otherwise
- Return type
int
See Window layer for more information.
Thus, if you have a window at the front of the floating window layer (
WindowLayerFloatingWindows), this will return true even if there is a modal window (in layerWindowLayerModal) above you. (Not to worry, though: in such a case, X-Plane will not pass clicks or keyboard input down to your layer until the window above stops “eating” the input.)Note that legacy windows are always placed in layer
WindowLayerFlightOverlay, while modern-style windows default toWindowLayerFloatingWindows. This means it’s perfectly consistent to have two different plugin-created windows (one legacy, one modern) both be in the front (of their different layers!) at the same time.Official SDK: XPLMIsWindowInFront
