X-Plane 11 Window Gravity Sample

This example demonstrates how the use of the XPLMSetWindowGravity() API to cause your window to dynamically resize based on the X-Plane window's size.

The gravity API keeps the SDK-created window fixed to the left and right sides, so it grows & shrinks with the X‑Plane window.

#include "XPLMDisplay.h"
#include "XPLMGraphics.h"
#include <string.h>
#include <stdio.h>
#if IBM
	#include <windows.h>
#elif LIN
	#include <GL/gl.h>
#elif __GNUC__
	#include <OpenGL/gl.h>
	#include <GL/gl.h>

#ifndef XPLM300
	#error This is made to be compiled against the XPLM300 SDK

static XPLMWindowID	g_window;

void				draw(XPLMWindowID in_window_id, void * in_refcon);

int					dummy_mouse_handler(XPLMWindowID in_window_id, int x, int y, int is_down, void * in_refcon) { return 0; }
XPLMCursorStatus	dummy_cursor_status_handler(XPLMWindowID in_window_id, int x, int y, void * in_refcon) { return xplm_CursorDefault; }
int					dummy_wheel_handler(XPLMWindowID in_window_id, int x, int y, int wheel, int clicks, void * in_refcon) { return 0; }
void				dummy_key_handler(XPLMWindowID in_window_id, char key, XPLMKeyFlags flags, char virtual_key, void * in_refcon, int losing_focus) { }

PLUGIN_API int XPluginStart(
						char *		outName,
						char *		outSig,
						char *		outDesc)
	strcpy(outName, "GravitySamplePlugin");
	strcpy(outSig, "xpsdk.examples.gravitysampleplugin");
	strcpy(outDesc, "A test plug-in that demonstrates the gravity features of the X-Plane 11 GUI plugin API.");

	// We're not guaranteed that the main monitor's lower left is at (0, 0)... we'll need to query for the global desktop bounds!
	int global_desktop_bounds[4]; // left, bottom, right, top
	XPLMGetScreenBoundsGlobal(&global_desktop_bounds[0], &global_desktop_bounds[3], &global_desktop_bounds[2], &global_desktop_bounds[1]);

	XPLMCreateWindow_t params;
	params.structSize = sizeof(params);
	// Set the window bounds such that we stretch the full *width* of the global desktop, and cover the top 200 bx
	params.left = global_desktop_bounds[0];
	params.bottom = global_desktop_bounds[3] - 200;
	params.right = global_desktop_bounds[2];
	params.top = global_desktop_bounds[3];
	params.visible = 1;
	params.drawWindowFunc = draw;
	params.handleMouseClickFunc = dummy_mouse_handler;
	params.handleRightClickFunc = dummy_mouse_handler;
	params.handleMouseWheelFunc = dummy_wheel_handler;
	params.handleKeyFunc = dummy_key_handler;
	params.handleCursorFunc = dummy_cursor_status_handler;
	params.refcon = NULL;
	params.layer = xplm_WindowLayerFlightOverlay; // stick our window beneath all floating windows (like the X-Plane 11 map)
	params.decorateAsFloatingWindow = 0;
	g_window = XPLMCreateWindowEx(&params);
	XPLMSetWindowPositioningMode(g_window, xplm_WindowPositionFree, -1);
	// As the X-Plane window resizes, glue our left and right edges to the sides of the screen
	// (causing our width to grow and shrink to match the window size), but keep a constant
	// height for our window (with the same y position relative to the window's top).
	XPLMSetWindowGravity(g_window, 0, 1, 1, 1);
	return (g_window != NULL);

PLUGIN_API void	XPluginStop(void)
	// Since we created the window, we'll be good citizens and clean it up
	g_window = NULL;

PLUGIN_API void XPluginDisable(void) { }
PLUGIN_API int  XPluginEnable(void)  { return 1; }
PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, int inMsg, void * inParam) { }

void	draw(XPLMWindowID in_window_id, void * in_refcon)
			0 /* no fog */,
			0 /* 0 texture units */,
			0 /* no lighting */,
			0 /* no alpha testing */,
			1 /* do alpha blend */,
			1 /* do depth testing */,
			0 /* no depth writing */
	int b[4];
	XPLMGetWindowGeometry(in_window_id, &b[0], &b[3], &b[2], &b[1]);
	// Draw our window's translucent background overlay
	XPLMDrawTranslucentDarkBox(b[0], b[3], b[2], b[1]);
	// Display the window bounds (centered within the window)
	char scratch_buffer[150];
	sprintf(scratch_buffer, "Window bounds: %d %d %d %d", b[0], b[1], b[2], b[3]);
	float col_white[] = {1.0, 1.0, 1.0};
	int text_width = XPLMMeasureString(xplmFont_Proportional, scratch_buffer, strlen(scratch_buffer));
	float text_midpoint_x = (b[2] + b[0]) / 2;
	XPLMDrawString(col_white, text_midpoint_x - text_width / 2, (b[3] + b[1]) / 2, scratch_buffer, NULL, xplmFont_Proportional);

  • Facebook
  • Reddit
  • Twitter
  • LinkedIn

About Tyler Young

Tyler is a software developer for X-Plane. Among other projects, he was in charge of the new X-Plane 11 user interface.
Bookmark the permalink.

6 Responses to X-Plane 11 Window Gravity Sample

  1. Stef says:

    Thanks a lot Tyler,

    What's about using it on X-Plane v10 ?

    Probably a stupid question but where we can download the last SDK please ?


    • Tyler Young says:

      Shhh... you've found my super-secret SDK version 3.0 samples. 🙂 Version 3 of the SDK will be released with the impending X-Plane 11.10 release. (Watch the blog for an announcement on where to get it.)

      There are no plans to backport new SDK functionality to X-Plane 10, though.

      • Steve.Wilson says:

        Ah. Being stealthy, are we? 😉

        So the SDK will be updated sooner rather than later! That's really good news - and very important for commercial devs to know. New toys to play with, new ways to break old toys.


        Watching the blog like a hawk. 😀

      • Stef says:

        Hoo, I'm happy. Don't worry, I'll say no word 🙂
        I'm impatient to read more, The way appears to be simple to use and I'm sure you will enjoy plugin developers with that. GoodWay will be HAPPY to use it 🙂

        Don't worry, Shhhhhh.... 🙂 THANKS !!!!!


  2. Mark Ellis says:


    Is there a list of enhancements you are planning for the new SDK? I'm interested being able to create undocked windows and have scale-able fonts using XPStandardWidgets.

    I' also interested if we have a bit more control over the mouse events, like a right mouse click.


Leave a Reply

Your email address will not be published. Required fields are marked *