arsd.simpledisplay

simpledisplay.d provides basic cross-platform GUI-related functionality, including creating windows, drawing on them, working with the clipboard, timers, OpenGL, and more. However, it does NOT provide high level GUI widgets. See my minigui.d, an extension to this module, for that functionality.

Discussion

simpledisplay provides cross-platform wrapping for Windows and Linux (and perhaps other OSes that use X11), but also does not prevent you from using the underlying facilities if you need them. It has a goal of working efficiently over a remote X link (at least as far as Xlib reasonably allows.) simpledisplay depends on [arsd.color|color.d], which should be available from the same place where you got this file. Other than that, however, it has very few dependencies and ones that don't come with the OS and/or the compiler are all opt-in. simpledisplay.d's home base is on my arsd repo on Github. The file is:

https: //github.com/adamdruppe/arsd/blob/master/simpledisplay.d simpledisplay is basically stable. I plan to refactor the internals, and may add new features and fix bugs, but It do not expect to significantly change the API. It has been stable a few years already now.

Jump list: Don't worry, you don't have to read this whole documentation file! Check out the [#Event-example] and [#Pong-example] to get started quickly. The main classes you may want to create are [SimpleWindow], [Timer], [Image], and [Sprite]. The main functions you'll want are [setClipboardText] and [getClipboardText]. There are also platform-specific functions available such as [XDisplayConnection] and [GetAtom] for X11, among others. See the examples and topics list below to learn more. The goal here is to give some complete programs as overview examples first, then a look at each major feature with working examples first, then, finally, the inline class and method list will follow. Scan for headers for a topic - they will visually stand out - you're interested in to get started quickly and feel free to copy and paste any example as a starting point for your program. I encourage you to learn the library by experimenting with the examples! All examples are provided with no copyright restrictions whatsoever. You do not need to credit me or carry any kind of notice with the source if you copy and paste from them. To get started, download simpledisplay.d and color.d to a working directory. Copy an example info a file called example.d and compile using the command given at the top of each example. If you need help, email me: destructionator@gmail.com or IRC us, #d on Freenode (I am destructionator or adam_d_ruppe there). If you learn something that isn't documented, I appreciate pull requests on github to this file. At points, I will talk about implementation details in the documentation. These are sometimes subject to change, but nevertheless useful to understand what is really going on. You can learn more about some of the referenced things by searching the web for info about using them from C. You can always look at the source of simpledisplay.d too for the most authoritative source on its specific implementation. If you disagree with how I did something, please contact me so we can discuss it!

Examples

This program creates a window and draws events inside them as they happen, scrolling the text in the window as needed. Run this program and experiment to get a feel for where basic input events take place in the library.

  1. // dmd example.d simpledisplay.d color.d import arsd.simpledisplay; import std.conv; void main() { auto window = new SimpleWindow(Size(500, 500), "My D App"); int y = 0; void addLine(string text) { auto painter = window.draw(); if(y + painter.fontHeight >= window.height) { painter.scrollArea(Point(0, 0), window.width, window.height, 0, painter.fontHeight); y -= painter.fontHeight; } painter.outlineColor = Color.red; painter.fillColor = Color.black; painter.drawRectangle(Point(0, y), window.width, painter.fontHeight); painter.outlineColor = Color.white; painter.drawText(Point(10, y), text); y += painter.fontHeight; } window.eventLoop(1000, () { addLine("Timer went off!"); }, (KeyEvent event) { addLine(to!string(event)); }, (MouseEvent event) { addLine(to!string(event)); }, (dchar ch) { addLine(to!string(ch)); } ); }
This program creates a little Pong-like game. Player one is controlled with the keyboard. Player two is controlled with the mouse. It demos the pulse timer, event handling, and some basic drawing.
  1. // dmd example.d simpledisplay.d color.d import arsd.simpledisplay; enum paddleMovementSpeed = 8; enum paddleHeight = 48; void main() { auto window = new SimpleWindow(600, 400, "Pong game!"); int playerOnePosition, playerTwoPosition; int playerOneMovement, playerTwoMovement; int playerOneScore, playerTwoScore; int ballX, ballY; int ballDx, ballDy; void serve() { import std.random; ballX = window.width / 2; ballY = window.height / 2; ballDx = uniform(-4, 4) * 3; ballDy = uniform(-4, 4) * 3; if(ballDx == 0) ballDx = uniform(0, 2) == 0 ? 3 : -3; } serve(); window.eventLoop(50, // set a 50 ms timer pulls // This runs once per timer pulse delegate () { auto painter = window.draw(); painter.clear(); // Update everyone's motion playerOnePosition += playerOneMovement; playerTwoPosition += playerTwoMovement; ballX += ballDx; ballY += ballDy; // Bounce off the top and bottom edges of the window if(ballY + 7 >= window.height) ballDy = -ballDy; if(ballY - 8 <= 0) ballDy = -ballDy; // Bounce off the paddle, if it is in position if(ballX - 8 <= 16) { if(ballY + 7 > playerOnePosition && ballY - 8 < playerOnePosition + paddleHeight) { ballDx = -ballDx + 1; // add some speed to keep it interesting ballDy += playerOneMovement; // and y movement based on your controls too ballX = 24; // move it past the paddle so it doesn't wiggle inside } else { // Missed it playerTwoScore ++; serve(); } } if(ballX + 7 >= window.width - 16) { // do the same thing but for player 1 if(ballY + 7 > playerTwoPosition && ballY - 8 < playerTwoPosition + paddleHeight) { ballDx = -ballDx - 1; ballDy += playerTwoMovement; ballX = window.width - 24; } else { // Missed it playerOneScore ++; serve(); } } // Draw the paddles painter.outlineColor = Color.black; painter.drawLine(Point(16, playerOnePosition), Point(16, playerOnePosition + paddleHeight)); painter.drawLine(Point(window.width - 16, playerTwoPosition), Point(window.width - 16, playerTwoPosition + paddleHeight)); // Draw the ball painter.fillColor = Color.red; painter.outlineColor = Color.yellow; painter.drawEllipse(Point(ballX - 8, ballY - 8), Point(ballX + 7, ballY + 7)); // Draw the score painter.outlineColor = Color.blue; import std.conv; painter.drawText(Point(64, 4), to!string(playerOneScore)); painter.drawText(Point(window.width - 64, 4), to!string(playerTwoScore)); }, delegate (KeyEvent event) { // Player 1's controls are the arrow keys on the keyboard if(event.key == Key.Down) playerOneMovement = event.pressed ? paddleMovementSpeed : 0; if(event.key == Key.Up) playerOneMovement = event.pressed ? -paddleMovementSpeed : 0; }, delegate (MouseEvent event) { // Player 2's controls are mouse movement while the left button is held down if(event.type == MouseEventType.motion && (event.modifierState & ModifierState.leftButtonDown)) { if(event.dy > 0) playerTwoMovement = paddleMovementSpeed; else if(event.dy < 0) playerTwoMovement = -paddleMovementSpeed; } else { playerTwoMovement = 0; } } ); }
If you are interested in more game writing with D, check out my gamehelpers.d which builds upon simpledisplay, and its other stand-alone support modules, simpleaudio.d and joystick.d, too. This program displays a pie chart. Clicking on a color will increase its share of the pie.
The [SimpleWindow] class is simpledisplay's flagship feature. It represents a single window on the user's screen. You may create multiple windows, if the underlying platform supports it. You may check static if(multipleWindowsSupported) at compile time, or catch exceptions thrown by SimpleWindow's constructor at runtime to handle those cases. A single running event loop will handle as many windows as needed. setEventHandlers function eventLoop function draw function title property The simpledisplay event loop is designed to handle common cases easily while being extensible for more advanced cases, or replaceable by other libraries. The most common scenario is creating a window, then calling window.eventLoop when setup is complete. You can pass several handlers to the eventLoop method right there:
  1. // dmd example.d simpledisplay.d color.d import arsd.simpledisplay; void main() { auto window = new SimpleWindow(200, 200); window.eventLoop(0, delegate (dchar) { /* got a character key press */ } ); }
On Linux, the event loop is implemented with the epoll system call for efficiency an extensibility to other files. On Windows, it runs a traditional GetMessage + DispatchMessage loop, with a call to SleepEx in each iteration to allow the thread to enter an alertable wait state regularly, primarily so Overlapped I/O callbacks will get a chance to run. On Linux, simpledisplay also supports my arsd.eventloop module. Compile your program, including the eventloop.d file, with the -version=with_eventloop switch. It should be possible to integrate simpledisplay with vibe.d as well, though I haven't tried. Notification area icons are currently only implemented on X11 targets. Windows support will come when I need it (or if someone requests it and I have some time to spend on it). There are event handlers for low-level keyboard and mouse events, and higher level handlers for character events. To draw on your window, use the window.draw method. It returns a [ScreenPainter] structure with drawing methods.

Important: ScreenPainter double-buffers and will not actually update the window until its destructor is run. Always ensure the painter instance goes out-of-scope before proceeding. You can do this by calling it inside an event handler, a timer callback, or an small scope inside main. For example:

  1. // dmd example.d simpledisplay.d color.d import arsd.simpledisplay; void main() { auto window = new SimpleWindow(200, 200); { // introduce sub-scope auto painter = window.draw(); // begin drawing /* draw here */ painter.outlineColor = Color.red; painter.fillColor = Color.black; painter.drawRectangle(Point(0, 0), 200, 200); } // end scope, calling `painter`'s destructor, drawing to the screen. window.eventLoop(0); // handle events }
Painting is done based on two color properties, a pen and a brush. At this time, the 2d drawing does not support alpha blending. If you need that, use a 2d OpenGL context instead. FIXME add example of 2d opengl drawing here simpledisplay can create OpenGL contexts on your window. It works quite differently than 2d drawing. Note that it is still possible to draw 2d on top of an OpenGL window, using the draw method, though I don't recommend it. To start, you create a SimpleWindow with OpenGL enabled by passing the argument OpenGlOptions.yes to the constructor. Next, you set redrawOpenGlScene to a delegate which draws your frame. To force a redraw of the scene, call window.redrawOpenGlSceneNow(). Please note that my experience with OpenGL is very out-of-date, and the bindings in simpledisplay reflect that. If you want to use more modern functions, you may have to define the bindings yourself, or import them from another module. However, I believe the OpenGL context creation done in simpledisplay will work for any version. This example program will draw a rectangle on your window:
  1. // dmd example.d simpledisplay.d color.d import arsd.simpledisplay; void main() { }
You can also load PNG images using my png.d.
  1. // dmd example.d simpledisplay.d color.d png.d import arsd.simpledisplay; import arsd.png; void main() { auto image = Image.fromMemoryImage(readPng("image.png")); displayImage(image); }
Compile with dmd example.d simpledisplay.d png.d. If you find an image file which is a valid png that arsd.png fails to load, please let me know. In the mean time of fixing the bug, you can probably convert the file into an easier-to-load format. Be sure to turn OFF png interlacing, as that isn't supported. Other things to try would be making the image smaller, or trying 24 bit truecolor mode with an alpha channel. The [Sprite] class is used to make images on the display server for fast blitting to screen. This is especially important to use to support fast drawing of repeated images on a remote X11 link. The free functions [getClipboardText] and [setClipboardText] consist of simpledisplay's cross-platform clipboard support at this time. It also has helpers for handling X-specific events. There are two timers in simpledisplay: one is the pulse timeout you can set on the call to window.eventLoop, and the other is a customizable class, [Timer]. The pulse timeout is used by setting a non-zero interval as the first argument to eventLoop function and adding a zero-argument delegate to handle the pulse.
  1. import arsd.simpledisplay; void main() { auto window = new SimpleWindow(400, 400); // every 100 ms, it will draw a random line // on the window. window.eventLoop(100, { auto painter = window.draw(); import std.random; // random color painter.outlineColor = Color(uniform(0, 256), uniform(0, 256), uniform(0, 256)); // random line painter.drawLine( Point(uniform(0, window.width), uniform(0, window.height)), Point(uniform(0, window.width), uniform(0, window.height))); }); }
The Timer class works similarly, but is created separately from the event loop. (It still fires through the event loop, though.) You may make as many instances of Timer as you wish. The pulse timer and instances of the [Timer] class may be combined at will.
  1. import arsd.simpledisplay; void main() { auto window = new SimpleWindow(400, 400); auto timer = new Timer(1000, delegate { auto painter = window.draw(); painter.clear(); }); window.eventLoop(0); }
Timers are currently only implemented on Windows, using SetTimer and Linux, using timerfd_create. These deliver timeout messages through your application event loop. simpledisplay carries a lot of code to help implement itself without extra dependencies, and much of this code is available for you too, so you may extend the functionality yourself. See also: xwindows.d from my github. handleNativeEvent and handleNativeGlobalEvent. Integration with a third-party event loop is possible. On Linux, you might want to support both terminal input and GUI input. You can do this by using simpledisplay together with eventloop.d and terminal.d. simpledisplay does not provide GUI widgets such as text areas, buttons, checkboxes, etc. It only gives basic windows, the ability to draw on it, receive input from it, and access native information for extension. You may write your own gui widgets with these, but you don't have to because I already did for you! Download minigui.d from my github repository and add it to your project. minigui builds these things on top of simpledisplay and offers its own Window class (and subclasses) to use that wrap SimpleWindow, adding a new event and drawing model that is hookable by subwidgets, represented by their own classes. Migrating to minigui from simpledisplay is often easy though, because they both use the same ScreenPainter API, and the same simpledisplay events are available, if you want them. (Though you may like using the minigui model, especially if you are familiar with writing web apps in the browser with Javascript.) minigui still needs a lot of work to be finished at this time, but it already offers a number of useful classes. I don't have a Mac, so that code isn't maintained. I would like to have a Cocoa implementation though. The NativeSimpleWindowImplementation and NativeScreenPainterImplementation both suck. If I was rewriting it, I wouldn't do it that way again. This file must not have any more required dependencies. If you need bindings, add them right to this file. Once it gets into druntime and is there for a while, remove bindings from here to avoid conflicts (or put them in an appropriate version block so it continues to just work on old dmd), but wait a couple releases before making the transition so this module remains usable with older versions of dmd. You may have optional dependencies if needed by putting them in version blocks or template functions. You may also extend the module with other modules with UFCS without actually editing this - that is nice to do if you can. Try to make functions work the same way across operating systems. I typically make it thinly wrap Windows, then emulate that on Linux. A goal of this is to keep a gui hello world to less than 250 KB. This means avoiding Phobos! So try to avoid it. See more comments throughout the source. I realize this file is fairly large, but over half that is just bindings at the bottom or documentation at the top. Some of the classes are a bit big too, but hopefully easy to understand. I suggest you jump around the source by looking for a particular declaration you're interested in, like class SimpleWindow using your editor's search function, then look at one piece at a time.

Authors

Adam D. Ruppe with the help of others. If you need help, please email me with destructionator@gmail.com or find me on IRC. Our channel is #d on Freenode. I go by Destructionator or adam_d_ruppe, depending on which computer I'm logged into. I live in the eastern United States, so I will most likely not be around at night in that US east timezone.

License

Copyright Adam D. Ruppe, 2011-2016. Released under the Boost Software License. Building documentation: You may wish to use the arsd.ddoc file from my github with building the documentation for simpledisplay yourself. It will give it a bit more style. Simply download the arsd.ddoc file and add it to your compile command when building docs. dmd -c simpledisplay.d color.d -D arsd.ddoc

  • Declaration

    enum bool UsingSimpledisplayX11;

    If you have to get down and dirty with implementation details, this helps figure out if X is available you can static if(UsingSimpledisplayX11) ... more reliably than version() because version is module-local.

  • Declaration

    enum bool multipleWindowsSupported;

    Does this platform support multiple windows? If not, trying to create another will cause it to throw an exception.

  • Declaration

    enum WindowFlags: int;

    After selecting a type from [WindowTypes], you may further customize its behavior by setting one or more of these flags.

    Discussion

    The different window types have different meanings of normal. If the window type already is a good match for what you want to do, you should just use [WindowFlags.normal], the default, which will do the right thing for your users.

  • Declaration

    enum WindowTypes: int;

    When creating a window, you can pass a type to SimpleWindow's constructor, then further customize the window by changing WindowFlags.

    Discussion

    This list is based on the EMWH spec for X11.

    http: //standards.freedesktop.org/wm-spec/1.4/ar01s05.html#idm139704063786896

    • Declaration

      normal

      An ordinary application window.

    • Declaration

      undecorated

      A generic window without a title bar or border. You can draw on the entire area of the screen it takes up and use it as you wish. Remember that users don't really expect these though, so don't use it where a window of any other type is appropriate.

  • Declaration

    void setOpenGLContextVersion()(ubyte hi, ubyte lo);

    Set OpenGL context version to use. This has no effect on non-OpenGL windows. You may want to change context version if you want to use advanced shaders or other modern OpenGL techinques. This setting doesn't affect already created windows. You may use version 2.1 as your default, which should be supported by any box since 2006, so seems to be a reasonable choice.

    Discussion

    Note that by default version is set to 0, which forces SimpleDisplay to use old context creation code without any version specified. This is the safest way to init OpenGL, but it may not give you access to advanced features. See available OpenGL versions here: https://en.wikipedia.org/wiki/OpenGL

  • Declaration

    @property void openGLContextCompatible()(bool v);

    Set OpenGL context mode. Modern (3.0+) OpenGL versions deprecated old fixed pipeline functions, and without "compatible" mode you won't be able to use your old non-shader-based code with such contexts. By default SimpleDisplay creates compatible context, so you can gradually upgrade your OpenGL code if you want to (or leave it as is, as it should "just work").

  • Declaration

    @property void openGLContextAllowFallback()(bool v);

    Set to true to allow creating OpenGL context with lower version than requested instead of throwing. If fallback was activated (or legacy OpenGL was requested), openGLContextFallbackActivated() will return true.

  • Declaration

    @property bool openGLContextFallbackActivated()();

    After creating OpenGL window, you can check this to see if you got only "legacy" OpenGL context.

  • Declaration

    void sdpyWindowClass(const(char)[] v);

    Set window class name for all following new SimpleWindow() calls.

    Discussion

    WARNING! For Windows, you should set your class name before creating any window, and NEVER change it after that!

  • Declaration

    string sdpyWindowClass();

    Get current window class name.

  • Declaration

    class SimpleWindow: arsd.simpledisplay.CapableOfHandlingNativeEvent;

    The flagship window class.

    Discussion

    SimpleWindow tries to make ordinary windows very easy to create and use without locking you out of more advanced or complex features of the underlying windowing system. For many applications, you can simply call new SimpleWindow(some_width, some_height, "some title") and get a suitable window to work with. From there, you can opt into additional features, like custom resizability and OpenGL support with the next two constructor arguments. Or, if you need even more, you can set a window type and customization flags with the final two constructor arguments. If none of that works for you, you can also create a window using native function calls, then wrap the window in a SimpleWindow instance by calling new SimpleWindow(native_handle). Remember, though, if you do this, managing the window is still your own responsibility! Notably, you will need to destroy it yourself.

    • Declaration

      this(int width = 640, int height = 480, string title = null, OpenGlOptions opengl = OpenGlOptions.no, Resizablity resizable = Resizablity.automaticallyScaleIfPossible, WindowTypes windowType = WindowTypes.normal, int customizationFlags = WindowFlags.normal, SimpleWindow parent = null);

      This creates a window with the given options. The window will be visible and able to receive input as soon as you start your event loop. You may draw on it immediately after creating the window, without needing to wait for the event loop to start if you want.

      Discussion

      The constructor tries to have sane default arguments, so for many cases, you only need to provide a few of them.

      Parameters

      int width

      the width of the window's client area, in pixels

      int height

      the height of the window's client area, in pixels

      string title

      the title of the window (seen in the title bar, taskbar, etc.). You can change it after construction with the [SimpleWindow.title\ property.

      OpenGlOptions opengl

      [OpenGlOptions] are yes and no. If yes, it creates an OpenGL context on the window.

      Resizablity resizable

      [Resizablity] has three options:

      allowResizing, which allows the window to be resized by the user. The windowResized delegate will be called when the size is changed.

      fixedSize will not allow the user to resize the window.

      automaticallyScaleIfPossible will allow the user to resize, but will still present the original size to the API user. The contents you draw will be scaled to the size the user chose. If this scaling is not efficient, the window will be fixed size. The windowResized event handler will never be called. This is the default.

      WindowTypes windowType

      The type of window you want to make.

      int customizationFlags

      A way to make a window without a border, always on top, skip taskbar, and more. Do not use this if one of the pre-defined [WindowTypes], given in the windowType argument, is a good match for what you need.

      SimpleWindow parent

      the parent window, if applicable

    • Declaration

      this(Size size, string title = null, OpenGlOptions opengl = OpenGlOptions.no, Resizablity resizable = Resizablity.automaticallyScaleIfPossible);

      Same as above, except using the Size struct instead of separate width and height.

    • Declaration

      this(Image image, string title = null);

      Creates a window based on the given [Image]. It's client area width and height is equal to the image. (A window's client area is the drawable space inside; it excludes the title bar, etc.)

      Discussion

      Windows based on images will not be resizable and do not use OpenGL.

    • Declaration

      this(NativeWindowHandle nativeWindow);

      Wraps a native window handle with very little additional processing - notably no destruction this is incomplete so don't use it for much right now. The purpose of this is to make native windows created through the low level API (so you can use platform-specific options and other details SimpleWindow does not expose) available to the event loop wrappers.

    • Declaration

      void requestAttention();

      Requests attention from the user for this window.

      Discussion

      The typical result of this function is to change the color of the taskbar icon, though it may be tweaked on specific platforms. It is meant to unobtrusively tell the user that something relevant to them happened in the background and they should check the window when they get a chance. Upon receiving the keyboard focus, the window will automatically return to its natural state. If the window already has the keyboard focus, this function may do nothing, because the user is presumed to already be giving the window attention.

      Implementation note: requestAttention uses the NET_WM_STATE_DEMANDS_ATTENTION atom on X11 and the FlashWindow function on Windows.

    • Declaration

      void delegate() closeQuery;

      This will be called when WM wants to close your window (i.e. user clicked "close" icon, for example).

      Discussion

      You'll have to call close() manually if you set this delegate.

    • Declaration

      void delegate(bool becomesVisible) visibilityChanged;

      This will be called when window visibility was changed.

    • Declaration

      final @property bool closed();

      Returns true if the window has been closed.

    • Declaration

      final @property bool visible();

      Returns true if the window is visible (mapped).

    • Declaration

      void close();

      Closes the window. If there are no more open windows, the event loop will terminate.

    • Declaration

      void show();

      Alias for hidden = false

    • Declaration

      void hide();

      Alias for hidden = true

    • Declaration

      void hideCursor();

      Hide cursor when it enters the window.

    • Declaration

      void showCursor();

      Don't hide cursor when it enters the window.

    • Declaration

      bool warpMouse(int x, int y);

      "Warp" mouse pointer to coordinates relative to window top-left corner. Return "success" flag.

      Discussion

      Currently only supported on X11, so Windows implementation will return false.

      Note: "warping" pointer will not send any synthesised mouse events, so you probably doesn't want to use it to move mouse pointer to some active GUI area, for example, as your window won't receive "mouse moved here" event.

    • Declaration

      void sendDummyEvent();

      Send dummy window event to ping event loop. Required to process NotificationIcon on X11, for example.

    • Declaration

      void setMinSize(int minwidth, int minheight);

      Set window minimal size.

    • Declaration

      void setMaxSize(int maxwidth, int maxheight);

      Set window maximal size.

    • Declaration

      void setResizeGranularity(int granx, int grany);

      Set window resize step (window size will be changed with the given granularity on supported platforms).

      Discussion

      Currently only supported on X11.

    • Declaration

      void move(int x, int y);

      Move window.

    • Declaration

      void resize(int w, int h);

      Resize window.

    • Declaration

      void moveResize(int x, int y, int w, int h);

      Move and resize window (this can be faster and more visually pleasant than doing it separately).

    • Declaration

      final @property bool hidden();

      Returns true if the window is hidden.

    • Declaration

      final @property void hidden(bool b);

      Shows or hides the window based on the bool argument.

    • Declaration

      void setEventHandlers(T...)(T eventHandlers);

      Sets your event handlers, without entering the event loop. Useful if you have multiple windows - set the handlers on each window, then only do eventLoop on your main window.

    • Declaration

      final int eventLoop(T...)(long pulseTimeout, T eventHandlers);

      The event loop automatically returns when the window is closed

      Discussion

      pulseTimeout is given in milliseconds. If pulseTimeout == 0, no pulse timer is created. The event loop will block until an event arrives or the pulse timer goes off.

    • Declaration

      ScreenPainter draw();

      This lets you draw on the window (or its backing buffer) using basic 2D primitives.

      Discussion

      Be sure to call this in a limited scope because your changes will not actually appear on the window until ScreenPainter's destructor runs.

      Return Value

      an instance of [ScreenPainter], which has the drawing methods on it to draw on this window.

    • Declaration

      final @property int width();

      Width of the window's drawable client area, in pixels.

    • Declaration

      final @property int height();

      Height of the window's drawable client area, in pixels.

    • Declaration

      void delegate() redrawOpenGlScene;

      Put your code in here that you want to be drawn automatically when your window is uncovered. Set a handler here *before* entering your event loop any time you pass OpenGlOptions.yes to the constructor. Ideally, you will set this delegate immediately after constructing the SimpleWindow.

    • Declaration

      final @property void vsync(bool wait);

      This will allow you to change OpenGL vsync state.

    • Declaration

      void mtUnlock();

      "Unlock" this window handle, to do multithreaded synchronization. You probably won't need

      Discussion

      to call this, as it's not recommended to share window between threads.

    • Declaration

      void beep();

      Emit a beep to get user's attention.

    • Declaration

      bool useGLFinish;

      Set this to false if you don't need to do glFinish() after swapOpenGlBuffers().

      Discussion

      Note that at least NVidia proprietary driver may segfault if you will modify texture fast enough without waiting 'em to finish their frame bussiness.

    • Declaration

      void redrawOpenGlSceneNow();

      call this to invoke your delegate. It automatically sets up the context and flips the buffer. If you need to redraw the scene in response to an event, call this.

    • Declaration

      void setAsCurrentOpenGlContext();

      Makes all gl* functions target this window until changed. This is only valid if you passed OpenGlOptions.yes to the constructor.

    • Declaration

      nothrow bool setAsCurrentOpenGlContextNT();

      Makes all gl* functions target this window until changed. This is only valid if you passed OpenGlOptions.yes to the constructor.

      Discussion

      This doesn't throw, returning success flag instead.

    • Declaration

      nothrow bool releaseCurrentOpenGlContext();

      Releases OpenGL context, so it can be reused in, for example, different thread. This is only valid if you passed OpenGlOptions.yes to the constructor.

      Discussion

      This doesn't throw, returning success flag instead.

    • Declaration

      void swapOpenGlBuffers();

      simpledisplay always uses double buffering, usually automatically. This manually swaps the OpenGL buffers.

      Discussion

      You should not need to call this yourself because simpledisplay will do it for you after calling your redrawOpenGlScene. Remember that this may throw an exception, which you can catch in a multithreaded application to keep your thread from dying from an unhandled exception.

    • Declaration

      @property void title(string title);

      Set the window title, which is visible on the window manager title bar, operating system taskbar, etc.

      Discussion

      1. auto window = new SimpleWindow(100, 100, "First title"); window.title = "A new title";
      You may call this function at any time.

    • Declaration

      @property string title();

      Gets the title

    • Declaration

      @property void icon(MemoryImage icon);

      Set the icon that is seen in the title bar or taskbar, etc., for the user.

    • Declaration

      @property void image(Image i);

      Draws an image on the window. This is meant to provide quick look

      Discussion

      of a static image generated elsewhere.

    • Declaration

      void delegate(KeyEvent ke) handleKeyEvent;

      What follows are the event handlers. These are set automatically

      Discussion

      by the eventLoop function, but are still public so you can change them later. wasPressed == true means key down. false == key up. Handles a low-level keyboard event. Settable through setEventHandlers.

    • Declaration

      void delegate(dchar c) handleCharEvent;

      Handles a higher level keyboard event - c is the character just pressed. Settable through setEventHandlers.

    • Declaration

      void delegate() handlePulse;

      Handles a timer pulse. Settable through setEventHandlers.

    • Declaration

      void delegate(bool) onFocusChange;

      called when the focus changes, param is if we have it (true) or are losing it (false)

    • Declaration

      void delegate(MouseEvent) handleMouseEvent;

      Mouse event handler. Settable through setEventHandlers.

    • Declaration

      void delegate() paintingFinished;

      use to redraw child widgets if you use system apis to add stuff

    • Declaration

      void delegate(int width, int height) windowResized;

      handle a resize, after it happens. You must construct the window with Resizablity.allowResizing

      Discussion

      for this to ever happen.

    • Declaration

      NativeEventHandler handleNativeEvent;

      Platform specific - handle any native messages this window gets.

      Note: this is called *in addition to* other event handlers, unless you return zero indicating that you handled it. On Windows, it takes the form of int delegate(HWND,UINT, WPARAM, LPARAM). On X11, it takes the form of int delegate(XEvent).

      IMPORTANT: it used to be static in old versions of simpledisplay.d, but I always used it as if it wasn't static... so now I just fixed it so it isn't anymore.

    • Declaration

      static NativeEventHandler handleNativeGlobalEvent;

      This is the same as handleNativeEvent, but static so it can hook ALL events in the loop.

      Discussion

      If you used to use handleNativeEvent depending on it being static, just change it to use this instead and it will work the same way.

    • Declaration

      @property bool eventQueueEmpty()();

      Is our custom event queue empty? Can be used in simple cases to prevent "spamming" window with events it can't cope with. It is safe to call this from non-UI threads.

      Discussion

      This is in-process one-way (from anything to window) event sending mechanics. It is thread-safe, so it can be used in multi-threaded applications to send, for example, "wake up and repaint" events when thread completed some operation. This will allow to avoid using timer pulse to check events with synchronization, 'cause event handler will be called in UI thread. You can stop guessing which pulse frequency will be enough for your app. Note that events handlers may be called in arbitrary order, i.e. last registered handler can be called first, and vice versa.

    • Declaration

      @property bool eventQueued(ET : Object)();

      Does our custom event queue contains at least one with the given type? Can be used in simple cases to prevent "spamming" window with events it can't cope with. It is safe to call this from non-UI threads.

      Discussion

      This is in-process one-way (from anything to window) event sending mechanics. It is thread-safe, so it can be used in multi-threaded applications to send, for example, "wake up and repaint" events when thread completed some operation. This will allow to avoid using timer pulse to check events with synchronization, 'cause event handler will be called in UI thread. You can stop guessing which pulse frequency will be enough for your app. Note that events handlers may be called in arbitrary order, i.e. last registered handler can be called first, and vice versa.

    • Declaration

      uint addEventListener(ET : Object)(void delegate(ET) dg);

      Add listener for custom event. Can be used like this:

      Discussion

      1. auto eid = win.addEventListener((MyStruct evt) { ... }); ... win.removeEventListener(eid);

      Return Value

      0 on failure (should never happen, so ignore it) This is in-process one-way (from anything to window) event sending mechanics. It is thread-safe, so it can be used in multi-threaded applications to send, for example, "wake up and repaint" events when thread completed some operation. This will allow to avoid using timer pulse to check events with synchronization, 'cause event handler will be called in UI thread. You can stop guessing which pulse frequency will be enough for your app. Note that events handlers may be called in arbitrary order, i.e. last registered handler can be called first, and vice versa.

    • Declaration

      void removeEventListener()(uint id);

      Remove event listener. It is safe to pass invalid event id here.

      Discussion

      This is in-process one-way (from anything to window) event sending mechanics. It is thread-safe, so it can be used in multi-threaded applications to send, for example, "wake up and repaint" events when thread completed some operation. This will allow to avoid using timer pulse to check events with synchronization, 'cause event handler will be called in UI thread. You can stop guessing which pulse frequency will be enough for your app. Note that events handlers may be called in arbitrary order, i.e. last registered handler can be called first, and vice versa.

    • Declaration

      bool postTimeout(ET : Object)(ET evt, uint timeoutmsecs);

      Post event to queue. It is safe to call this from non-UI threads.

      Discussion

      If timeoutmsecs is greater than zero, the event will be delayed for at least timeoutmsecs milliseconds. This is in-process one-way (from anything to window) event sending mechanics. It is thread-safe, so it can be used in multi-threaded applications to send, for example, "wake up and repaint" events when thread completed some operation. This will allow to avoid using timer pulse to check events with synchronization, 'cause event handler will be called in UI thread. You can stop guessing which pulse frequency will be enough for your app. Note that events handlers may be called in arbitrary order, i.e. last registered handler can be called first, and vice versa.

    • Declaration

      bool postEvent(ET : Object)(ET evt);

      Post event to queue. It is safe to call this from non-UI threads.

      Discussion

      This is in-process one-way (from anything to window) event sending mechanics. It is thread-safe, so it can be used in multi-threaded applications to send, for example, "wake up and repaint" events when thread completed some operation. This will allow to avoid using timer pulse to check events with synchronization, 'cause event handler will be called in UI thread. You can stop guessing which pulse frequency will be enough for your app. Note that events handlers may be called in arbitrary order, i.e. last registered handler can be called first, and vice versa.

  • Declaration

    class Timer;

    A timer that will trigger your function on a given interval.

    Discussion

    You create a timer with an interval and a callback. It will continue to fire on the interval until it is destroyed. There are currently no one-off timers (instead, just create one and destroy it when it is triggered) nor are there pause/resume functions - the timer must again be destroyed and recreated if you want to pause it. auto timer = new Timer(50, { it happened!; }); timer.destroy(); Timers can only be expected to fire when the event loop is running.

    • Declaration

      this(int intervalInMilliseconds, void delegate() onPulse);

      Create a timer with a callback when it triggers.

    • Declaration

      void destroy();

      Stop and destroy the timer object.

  • Declaration

    void getClipboardText(SimpleWindow clipboardOwner, void delegate(in char[]) receiver);

    this does a delegate because it is actually an async call on X...

    Discussion

    the receiver may never be called if the clipboard is empty or unavailable gets plain text from the clipboard

  • Declaration

    void setClipboardText(SimpleWindow clipboardOwner, string text);

    copies some text to the clipboard

  • Declaration

    @property Atom GetAtom(string name, bool create = false)(Display* display);

    Platform specific for X11

  • Declaration

    void setPrimarySelection(SimpleWindow window, string text);

    Asserts ownership of PRIMARY and copies the text into a buffer that clients can request later

  • Declaration

    void setSecondarySelection(SimpleWindow window, string text);

    Asserts ownership of SECONDARY and copies the text into a buffer that clients can request later

  • Declaration

    void setX11Selection(string atomName)(SimpleWindow window, string text);

  • Declaration

    void getPrimarySelection(SimpleWindow window, void delegate(in char[]) handler);

  • Declaration

    void getX11Selection(string atomName)(SimpleWindow window, void delegate(in char[]) handler);

  • Declaration

    void[] getX11PropertyData(Window window, Atom property, Atom type = AnyPropertyType);

  • Declaration

    class NotificationAreaIcon: arsd.simpledisplay.CapableOfHandlingNativeEvent;

    • Declaration

      this(string name, MemoryImage icon, void delegate(MouseButton button) onClick);

    • Declaration

      this(string name, Image icon, void delegate(MouseButton button) onClick);

  • Declaration

    void sendSyntheticInput(wstring s);

    Platform-specific for Windows. Sends a string as key press and release events to the actively focused window (not necessarily your application)

  • Declaration

    int registerHotKey(SimpleWindow window, uint modifiers, uint vk, void delegate() handler);

    Platform-specific for Windows. Registers a global hotkey. Returns a registration ID.

  • Declaration

    void unregisterHotKey(SimpleWindow window, int id);

    Platform-specific for Windows. Unregisters a key. The id is the value returned by registerHotKey.

  • Declaration

    enum RasterOp: int;

    [ScreenPainter] operations can use different operations to combine the color with the color on screen.

    See Also

    • Declaration

      normal

      Replaces the pixel.

    • xor

      Declaration

      xor

      Uses bitwise xor to draw.

  • Declaration

    enum OpenGlOptions: int;

    Determines if you want an OpenGL context created on the new window.

    Discussion

    See more: [#topics-3d|in the 3d topic].

    1. import arsd.simpledisplay; void main() { auto window = new SimpleWindow(500, 500, "OpenGL Test", OpenGlOptions.yes); // Set up the matrix window.setAsCurrentOpenGlContext(); // make this window active // This is called on each frame, we will draw our scene window.redrawOpenGlScene = delegate() { }; window.eventLoop(0); }

    • no

      Declaration

      no

      No OpenGL context is created

    • yes

      Declaration

      yes

      Yes, create an OpenGL context

  • Declaration

    enum Resizablity: int;

    When you create a SimpleWindow, you can see its resizability to be one of these via the constructor...

    • Declaration

      fixedSize

      the window cannot be resized

    • Declaration

      allowResizing

      the window can be resized. The buffer (if there is one) will automatically adjust size, but not stretch the contents. the windowResized delegate will be called so you can respond to the new size yourself.

    • Declaration

      automaticallyScaleIfPossible

      if possible, your drawing buffer will remain the same size and simply be automatically scaled to the new window size. If this is impossible, it will not allow the user to resize the window at all. Note: window.width and window.height WILL be adjusted, which might throw you off if you draw based on them, so keep track of your expected width and height separately. That way, when it is scaled, things won't be thrown off.

  • Declaration

    enum TextAlignment: uint;

    Alignment for . Left, Center, or Right may be combined with VerticalTop, VerticalCenter, or VerticalBottom via bitwise or.

  • Declaration

    struct KeyEvent;

    Keyboard press and release events

    • key

      Declaration

      Key key;

      see table below. Always use the symbolic names, even for ASCII characters, since the actual numbers vary across platforms. See [Key]

    • Declaration

      uint hardwareCode;

      A platform and hardware specific code for the key

    • Declaration

      bool pressed;

      true if the key was just pressed, false if it was just released. note: released events aren't always sent...

    • Declaration

      dchar character;

    • Declaration

      uint modifierState;

      see enum [ModifierState]. They are bitwise combined together.

    • Declaration

      SimpleWindow window;

      associated Window

  • Declaration

    enum MouseEventType: int;

    Type of a [MouseEvent]

    • Declaration

      motion

      The mouse moved inside the window

    • Declaration

      buttonPressed

      A mouse button was pressed or the wheel was spun

    • Declaration

      buttonReleased

      A mouse button was released

  • Declaration

    struct MouseEvent;

    Listen for this on your event listeners if you are interested in mouse action.

    • Declaration

      MouseEventType type;

      movement, press, release, double click. See [MouseEventType]

    • x

      Declaration

      int x;

      Current X position of the cursor when the event fired, relative to the upper-left corner of the window, reported in pixels. (0, 0) is the upper left, (window.width - 1, window.height - 1) is the lower right corner of the window.

    • y

      Declaration

      int y;

      Current Y position of the cursor when the event fired.

    • dx

      Declaration

      int dx;

      Change in X position since last report

    • dy

      Declaration

      int dy;

      Change in Y position since last report

    • Declaration

      MouseButton button;

      See [MouseButton]

    • Declaration

      int modifierState;

      See [ModifierState]

    • Declaration

      SimpleWindow window;

      The window in which the event happened.

  • Pen

    Declaration

    struct Pen;

    This gives a few more options to drawing lines and such

    • Declaration

      Color color;

      the foreground color

    • Declaration

      int width;

      width of the line

    • Declaration

      Style style;

      See [Style] FIXME: not implemented

    • Declaration

      enum Style: int;

      NOT IMPLEMENTED

  • Declaration

    class Image;

    Represents an in-memory image in the format that the GUI expects, but with its raw data available to your program.

    Discussion

    On Windows, this means a device-independent bitmap. On X11, it is an XImage. Drawing an image to screen is not necessarily fast, but applying algorithms to draw to the image itself should be fast. An Image is also the first step in loading and displaying images loaded from files. If you intend to draw an image to screen several times, you will want to convert it into a [Sprite]. Drawing pixels on the image may be simple, using the opIndexAssign function, but you can also often get a fair amount of speedup by getting the raw data format and writing some custom code. FIXME INSERT EXAMPLES HERE

    • Declaration

      this(int width, int height);

    • Declaration

      this(Size size);

    • Declaration

      const pure nothrow @system int offsetForTopLeftPixel();

      if you do the math yourself you might be able to optimize it. Call these functions only once and cache the value.

    • Declaration

      const pure nothrow @system int offsetForPixel(int x, int y);

      if you do the math yourself you might be able to optimize it. Call these functions only once and cache the value.

    • Declaration

      const pure nothrow @system int adjustmentForNextLine();

      if you do the math yourself you might be able to optimize it. Call these functions only once and cache the value.

    • Declaration

      const pure nothrow @system int redByteOffset();

      once you have the position of a pixel, use these to get to the proper color

      Discussion

      if you do the math yourself you might be able to optimize it. Call these functions only once and cache the value.

    • Declaration

      const pure nothrow @system int greenByteOffset();

      if you do the math yourself you might be able to optimize it. Call these functions only once and cache the value.

    • Declaration

      const pure nothrow @system int blueByteOffset();

      if you do the math yourself you might be able to optimize it. Call these functions only once and cache the value.

    • Declaration

      final void putPixel(int x, int y, Color c);

    • Declaration

      final Color getPixel(int x, int y);

    • Declaration

      final void opIndexAssign(Color c, int x, int y);

    • Declaration

      TrueColorImage toTrueColorImage();

    • Declaration

      static Image fromMemoryImage(MemoryImage i);

    • Declaration

      ubyte[] getRgbaBytes(ubyte[] where = null);

      this is here for interop with arsd.image. where can be a TrueColorImage's data member

      Discussion

      if you pass in a buffer, it will put it right there. length must be width*height*4 already if you pass null, it will allocate a new one.

    • Declaration

      void setRgbaBytes(in ubyte[] from);

      this is here for interop with arsd.image. from can be a TrueColorImage's data member

    • Declaration

      ubyte* getDataPointer();

      warning: this is not portable across platforms because the data format can change

    • Declaration

      final const pure nothrow @safe int bytesPerLine();

      for use with getDataPointer

    • Declaration

      final const pure nothrow @safe int bytesPerPixel();

      for use with getDataPointer

    • Declaration

      immutable int width;

    • Declaration

      immutable int height;

  • Declaration

    void displayImage(Image image, SimpleWindow win = null);

    A convenience function to pop up a window displaying the image.

    Discussion

    If you pass a win, it will draw the image in it. Otherwise, it will create a window with the size of the image and run its event loop, closing when a key is pressed.

  • Declaration

    struct ScreenPainter;

    The 2D drawing proxy.

    Discussion

    Most functions use the outlineColor instead of taking a color themselves. ScreenPainter is reference counted and draws its buffer to the screen when its final reference goes out of scope.

    • Declaration

      int fontHeight();

    • pen

      Declaration

      @property void pen(Pen p);

    • Declaration

      @property void outlineColor(Color c);

    • Declaration

      @property void fillColor(Color c);

    • Declaration

      @property void rasterOp(RasterOp op);

    • Declaration

      void scrollArea(Point upperLeft, int width, int height, int dx, int dy);

      Scrolls the contents in the bounding rectangle by dx, dy. Positive dx means scroll left (make space available at the right), positive dy means scroll up (make space available at the bottom)

    • Declaration

      void clear();

    • Declaration

      void drawPixmap(Sprite s, Point upperLeft);

    • Declaration

      void drawImage(Point upperLeft, Image i, Point upperLeftOfImage = Point(0, 0), int w = 0, int h = 0);

    • Declaration

      Size textSize(string text);

    • Declaration

      void drawText(Point upperLeft, in char[] text, Point lowerRight = Point(0, 0), uint alignment = 0);

    • Declaration

      void drawPixel(Point where);

      Drawing an individual pixel is slow. Avoid it if possible.

    • Declaration

      void drawLine(Point starting, Point ending);

      Draws a pen using the current pen / outlineColor

    • Declaration

      void drawRectangle(Point upperLeft, int width, int height);

      Draws a rectangle using the current pen/outline color for the border and brush/fill color for the insides

      Discussion

      The outer lines, inclusive of x = 0, y = 0, x = width - 1, and y = height - 1 are drawn with the outlineColor The rest of the pixels are drawn with the fillColor. If fillColor is transparent, those pixels are not drawn.

    • Declaration

      void drawEllipse(Point upperLeft, Point lowerRight);

      Arguments are the points of the bounding rectangle

    • Declaration

      void drawPolygon(Point[] vertexes);

      .

  • Declaration

    class Sprite;

    Sprites are optimized for fast drawing on the screen, but slow for direct pixel access. They are best for drawing a relatively unchanging image repeatedly on the screen.

    Discussion

    On X11, this corresponds to an XPixmap. On Windows, it still uses a bitmap, though I'm not sure that's ideal and the implementation might change. You create one by giving a window and an image. It optimizes for that window, and copies the image into it to use as the initial picture. Creating a sprite can be quite slow (especially over a network connection) so you should do it as little as possible and just hold on to your sprite handles after making them. simpledisplay does try to do its best though, using the XSHM extension if available, but you should still write your code as if it will always be slow. Then you can use sprite.drawAt(painter, point); to draw it, which should be a fast operation - much faster than drawing the Image itself every time. Sprite represents a scarce resource which should be freed when you are done with it. Use the dispose method to do this. Do not use a Sprite after it has been disposed. If you are unsure about this, don't take chances, just let the garbage collector do it for you. But ideally, you can manage its lifetime more efficiently.

    FIXME: you are supposed to be able to draw on these similarly to on windows. ScreenPainter needs to be refactored to allow that though. So until that is done, consider a Sprite to have const contents.

    • Declaration

      this(SimpleWindow win, Image i);

      Makes a sprite based on the image with the initial contents from the Image

    • Declaration

      void drawAt(ScreenPainter painter, Point where);

      Draws the image on the specified painter at the specified point. The point is the upper-left point where the image will be drawn.

    • Declaration

      void dispose();

      Call this when you're ready to get rid of it

    • Declaration

      final @property int width();

    • Declaration

      final @property int height();

  • Declaration

    void flushGui();

    Flushes any pending gui buffers. Necessary if you are using with_eventloop with X - flush after you create your windows but before you call loop()

  • Declaration

    enum ModifierState: uint;

    State of keys on mouse events, especially motion.

    Discussion

    Do not trust the actual integer values in this, they are platform-specific. Always use the names.

  • Declaration

    enum MouseButton: int;

    The names assume a right-handed mouse. These are bitwise combined on the events that use them

  • Key

    Declaration

    enum Key: int;

    Do not trust the numeric values as they are platform-specific. Always use the symbolic name.

    • Declaration

      Escape

    • F1

      Declaration

      F1

    • F2

      Declaration

      F2

    • F3

      Declaration

      F3

    • F4

      Declaration

      F4

    • F5

      Declaration

      F5

    • F6

      Declaration

      F6

    • F7

      Declaration

      F7

    • F8

      Declaration

      F8

    • F9

      Declaration

      F9

    • F10

      Declaration

      F10

    • F11

      Declaration

      F11

    • F12

      Declaration

      F12

    • Declaration

      PrintScreen

    • Declaration

      ScrollLock

    • Declaration

      Pause

    • Declaration

      Grave

      The ` ~ key

    • N1

      Declaration

      N1

      Number key atop the keyboard

    • N2

      Declaration

      N2

    • N3

      Declaration

      N3

    • N4

      Declaration

      N4

    • N5

      Declaration

      N5

    • N6

      Declaration

      N6

    • N7

      Declaration

      N7

    • N8

      Declaration

      N8

    • N9

      Declaration

      N9

    • N0

      Declaration

      N0

    • Declaration

      Dash

    • Declaration

      Equals

    • Declaration

      Backslash

      The \ | key

    • Declaration

      Backspace

    • Declaration

      Insert

    • Declaration

      Home

    • Declaration

      PageUp

    • Declaration

      Delete

    • End

      Declaration

      End

    • Declaration

      PageDown

    • Up

      Declaration

      Up

    • Declaration

      Down

    • Declaration

      Left

    • Declaration

      Right

    • Tab

      Declaration

      Tab

    • Q

      Declaration

      Q

    • W

      Declaration

      W

    • E

      Declaration

      E

    • R

      Declaration

      R

    • T

      Declaration

      T

    • Y

      Declaration

      Y

    • U

      Declaration

      U

    • I

      Declaration

      I

    • O

      Declaration

      O

    • P

      Declaration

      P

    • Declaration

      LeftBracket

      the [ { key

    • Declaration

      RightBracket

      the ] } key

    • Declaration

      CapsLock

    • A

      Declaration

      A

    • S

      Declaration

      S

    • D

      Declaration

      D

    • F

      Declaration

      F

    • G

      Declaration

      G

    • H

      Declaration

      H

    • J

      Declaration

      J

    • K

      Declaration

      K

    • L

      Declaration

      L

    • Declaration

      Semicolon

    • Declaration

      Apostrophe

    • Declaration

      Enter

    • Declaration

      Shift

    • Z

      Declaration

      Z

    • X

      Declaration

      X

    • C

      Declaration

      C

    • V

      Declaration

      V

    • B

      Declaration

      B

    • N

      Declaration

      N

    • M

      Declaration

      M

    • Declaration

      Comma

    • Declaration

      Period

    • Declaration

      Slash

      the / ? key

    • Declaration

      Shift_r

      Note: this isn't sent on all computers, sometimes it just sends Shift, so don't rely on it. If it is supported though, it is the right Shift key, as opposed to the left Shift key

    • Declaration

      Ctrl

    • Declaration

      Windows

    • Alt

      Declaration

      Alt

    • Declaration

      Space

    • Declaration

      Alt_r

      ditto of shift_r

    • Declaration

      Windows_r

    • Declaration

      Menu

    • Declaration

      Ctrl_r

    • Declaration

      NumLock

    • Declaration

      Divide

      The / key on the number pad

    • Declaration

      Multiply

      The * key on the number pad

    • Declaration

      Minus

      The - key on the number pad

    • Declaration

      Plus

      The + key on the number pad

    • Declaration

      PadEnter

      Numberpad enter key

    • Declaration

      Pad1

      Numberpad keys

    • Declaration

      Pad2

    • Declaration

      Pad3

    • Declaration

      Pad4

    • Declaration

      Pad5

    • Declaration

      Pad6

    • Declaration

      Pad7

    • Declaration

      Pad8

    • Declaration

      Pad9

    • Declaration

      Pad0

    • Declaration

      PadDot

  • Declaration

    string xfontstr;

    This is the default font used. You might change this before doing anything else with

    Discussion

    the library if you want to try something else. Surround that in static if(UsingSimpledisplayX11) for cross-platform compatibility.

  • Declaration

    class XDisplayConnection;

    Platform-specific for X11. A singleton class (well, all its methods are actually static... so more like a namespace) wrapping a Display*

    • get

      Declaration

      static Display* get();

    • Declaration

      static void close();

  • Declaration

    bool doXNextEvent(Display* display);

    Platform-specific, you might use it when doing a custom event loop

  • Declaration

    void demandAttention(SimpleWindow window, bool needs = true);

    X-specific

  • Declaration

    TrueColorImage getWindowNetWmIcon(Window window);

    X-specific