FLTK 1.4.0
Loading...
Searching...
No Matches
Operating System Issues

This appendix describes the operating system specific interfaces in FLTK:

Accessing the OS Interfaces

All programs that need to access the operating system specific interfaces must include the following header file:

#include <FL/platform.H>

This header file will define the appropriate interface for your environment. The pages that follow describe the functionality that is provided for each operating system.

Note
These definitions used to be in FL/x.H up to FLTK 1.3.x. Usage of FL/x.H is deprecated since FLTK 1.4.0. You should replace all references of FL/x.H with FL/platform.H if your target is FLTK 1.4 or later. FL/x.H will be retained for backwards compatibility for some releases but will be removed in a later (not yet specified) FLTK release.

WARNING:

The interfaces provided by this header file may change radically in new FLTK releases. Use them only when an existing generic FLTK interface is not sufficient.

The Wayland/X11 hybrid library

By default, the FLTK library is, under Linux and Unix, a Wayland/X11 hybrid which can run FLTK-based apps as Wayland clients or as X11 clients. The choice between running an app as a Wayland or an X11 client is done as follows, when the app runs function fl_open_display() (that function can be called explicitly by the app or implicitly by FLTK, for example the first time an Fl_Window is show()'n) :

  • if the app contains a global boolean variable named fl_disable_wayland and this variable is true, X11 is used;
  • if environment variable FLTK_BACKEND is not defined, Wayland is used if a Wayland compositor is available, otherwise X11 is used;
  • if $FLTK_BACKEND equals "wayland", the library makes the app a Wayland client, and stops with error if no Wayland compositor is available;
  • if $FLTK_BACKEND equals "x11", the library makes the app an X11 client even if a Wayland compositor is available.

The first condition listed above is meant to facilitate conversion of code written for FLTK 1.3.x and containing X11-specific code; add this single statement anywhere in the app's source code:

FL_EXPORT bool fl_disable_wayland = true;
bool fl_disable_wayland
Prevent the FLTK library from using its Wayland backend and forces it to use its X11 backend.
Definition Fl.cxx:2191

and the app will always run as an X11 client.

After function fl_open_display() has been called, exactly one of the functions fl_wl_display() and fl_x11_display() returns a non-NULL value. When the former function does, the app runs as a Wayland client, and Wayland-specific functions and symbols described below (The Wayland Interface) can be used, whereas X11-specific functions and symbols cannot. Otherwise, the app runs as an X11 client, and only X11-specific functions and symbols below (The UNIX (X11) Interface) can be used.

Because a single app can be expected to run either Wayland or X11, it's necessary to use distinct names for global variables and functions in the X11- and the Wayland-specific source code.

Non-default configurations of the FLTK library under Linux/Unix are described in file README.Wayland.txt.

The UNIX (X11) Interface

Cross-platform applications should bracket X11-specific source code between #if defined(FLTK_USE_X11) / #endif and should ensure function fl_x11_display() returns non-NULL before calling X11-specific functions and using X11-specific symbols.

The UNIX interface provides access to the X Window System state information and data structures.

Handling Other X Events

void Fl::add_handler(int (*f)(int))

Installs a function to parse unrecognized events. If FLTK cannot figure out what to do with an event, it calls each of these functions (most recent first) until one of them returns non-zero. If none of them returns non-zero then the event is ignored.
FLTK calls this for any X events it does not recognize, or X events with a window ID that FLTK does not recognize. You can look at the X event in the fl_xevent variable.
The argument is the FLTK event type that was not handled, or zero for unrecognized X events. These handlers are also called for global shortcuts and some other events that the widget they were passed to did not handle, for example FL_SHORTCUT.

extern XEvent *fl_xevent

This variable contains the most recent X event.

extern ulong fl_event_time

This variable contains the time stamp from the most recent X event that reported it; not all events do. Many X calls like cut and paste need this value.

Window fl_xid(const Fl_Window *)

Returns the XID for a window, or zero if not shown().
Deprecated:
Kept for compatibility with FLTK versions before 1.4. Use preferentially fl_x11_xid(const Fl_Window *) with versions 1.4 and above.

Fl_Window *fl_find(ulong xid)

Returns the Fl_Window that corresponds to the given XID, or NULL if not found. This function uses a cache so it is slightly faster than iterating through the windows yourself.
Deprecated:
Kept for compatibility with FLTK versions before 1.4. Use preferentially fl_x11_find(Window) with versions 1.4 and above.

int fl_handle(const XEvent &)

This call allows you to supply the X events to FLTK, which may allow FLTK to cooperate with another toolkit or library. The return value is non-zero if FLTK understood the event. If the window does not belong to FLTK and the add_handler() functions all return 0, this function will return false.
Besides feeding events your code should call Fl::flush() periodically so that FLTK redraws its windows.
This function will call the callback functions. It will not return until they complete. In particular, if a callback pops up a modal window by calling fl_ask(), for instance, it will not return until the modal function returns.

Drawing using Xlib

The following global variables are set before Fl_Widget::draw() is called, or by Fl_Window::make_current():

extern Display *fl_display; // for compatibility with previous FLTK versions
extern Display *fl_x11_display(); // preferred access starting with FLTK 1.4
extern Window fl_window;
extern GC fl_gc; // for compatibility with previous FLTK versions
extern GC fl_x11_gc(); // preferred access starting with FLTK 1.4
extern int fl_screen;
extern XVisualInfo *fl_visual;
extern Colormap fl_colormap;
GC fl_x11_gc()
Returns the X11-specific currently active graphics context.
Display * fl_x11_display()
Returns the X11 Display in use.

You must use them to produce Xlib calls. Don't attempt to change them. A typical X drawing call is written like this:

XDrawSomething(fl_display, fl_window, fl_gc, ...);

Other information such as the position or size of the X window can be found by looking at Fl_Window::current(), which returns a pointer to the Fl_Window being drawn.

unsigned long fl_xpixel(Fl_Color i)
unsigned long fl_xpixel(uchar r, uchar g, uchar b)

Returns the X pixel number used to draw the given FLTK color index or RGB color. This is the X pixel that fl_color() would use.

int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b)

Convert a name into the red, green, and blue values of a color by parsing the X11 color names. On other systems, fl_parse_color() can only convert names in hexadecimal encoding, for example #ff8083.

extern XFontStruct *fl_xfont

Points to the font selected by the most recent fl_font(). This is not necessarily the current font of fl_gc, which is not set until fl_draw() is called. If FLTK was compiled with Xft support, fl_xfont will usually be 0 and fl_xftfont will contain a pointer to the XftFont structure instead.

extern void *fl_xftfont

If FLTK was compiled with Xft support enabled, fl_xftfont points to the xft font selected by the most recent fl_font(). Otherwise it will be 0. fl_xftfont should be cast to XftFont*.

Changing the Display, Screen, or X Visual

FLTK uses only a single display, screen, X visual, and X colormap. This greatly simplifies its internal structure and makes it much smaller and faster. You can change which it uses by setting global variables before the first Fl_Window::show() is called. You may also want to call Fl::visual(), which is a portable interface to get a full color and/or double buffered visual.

int Fl::display(const char *)

Set which X display to use. This actually does putenv("DISPLAY=...") so that child programs will display on the same screen if called with exec(). This must be done before the display is opened. This call is provided under MacOS and Windows but it has no effect.

extern Display *fl_display

The open X display. This is needed as an argument to most Xlib calls. Don't attempt to change it! This is NULL before the display is opened.

void fl_open_display()

Opens the display. Does nothing if it is already open. This will make sure fl_display is non-zero. You should call this if you wish to do X calls and there is a chance that your code will be called before the first show() of a window.
This may call Fl::abort() if there is an error opening the display.

void fl_x11_use_display(Display *d)

Directs FLTK to use a pre-established X11 connection.

void fl_close_display()

This closes the X connection. You do not need to call this to exit, and in fact it is faster to not do so! It may be useful to call this if you want your program to continue without the X connection. You cannot open the display again, and probably cannot call any FLTK functions.

extern int fl_screen

Which screen number to use. This is set by fl_open_display() to the default screen. You can change it by setting this to a different value immediately afterwards. It can also be set by changing the last number in the Fl::display() string to "host:0.#".

extern XVisualInfo *fl_visual
extern Colormap fl_colormap

The visual and colormap that FLTK will use for all windows. These are set by fl_open_display() to the default visual and colormap. You can change them before calling show() on the first window. Typical code for changing the default visual is:
Fl::args(argc, argv); // do this first so $DISPLAY is set
fl_visual = find_a_good_visual(fl_display, fl_screen);
if (!fl_visual) Fl::abort("No good visual");
fl_colormap = make_a_colormap(fl_display, fl_visual->visual, fl_visual->depth);
// it is now ok to show() windows:
window->show(argc, argv);
void fl_open_display()
Opens the display.
Definition Fl.cxx:2170
static int args(int argc, char **argv, int &i, Fl_Args_Handler cb=0)
Parse command line switches using the cb argument handler.
Definition Fl_arg.cxx:276

Using a Subclass of Fl_Window for Special X Stuff

FLTK can manage an X window on a different screen, visual and/or colormap, you just can't use FLTK's drawing routines to draw into it. But you can write your own draw() method that uses Xlib (and/or OpenGL) calls only.

FLTK can also manage XID's provided by other libraries or programs, and call those libraries when the window needs to be redrawn.

To do this, you need to make a subclass of Fl_Window and override some of these virtual functions:

virtual void Fl_Window::show()

If the window is already shown() this must cause it to be raised, this can usually be done by calling Fl_Window::show(). If not shown() your implementation must call either Fl_X::set_xid() or Fl_X::make_xid().
An example:
void MyWindow::show() {
if (shown()) {Fl_Window::show(); return;} // you must do this!
fl_open_display(); // necessary if this is first window
// we only calculate the necessary visual colormap once:
static XVisualInfo *visual;
static Colormap colormap;
if (!visual) {
visual = figure_out_visual();
colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
vis->visual, AllocNone);
}
Fl_X::make_xid(this, visual, colormap);
}
void show() FL_OVERRIDE
Puts the window on the screen.
Definition Fl_Window.cxx:545
Fl_X *Fl_X::set_xid(Fl_Window*, Window xid)
Allocate a hidden class called an Fl_X, put the XID into it, and set a pointer to it from the Fl_Window. This causes Fl_Window::shown() to return true.

void Fl_X::make_xid(Fl_Window*, XVisualInfo* = fl_visual, Colormap = fl_colormap)

This static method does the most onerous parts of creating an X window, including setting the label, resize limitations, etc. It then does Fl_X::set_xid() with this new window and maps the window.

virtual void Fl_Window::flush()

This virtual function is called by Fl::flush() to update the window. For FLTK's own windows it does this by setting the global variables fl_window and fl_gc and then calling the draw() method. For your own windows you might just want to put all the drawing code in here.
The X region that is a combination of all damage() calls done so far is in Fl_X::flx(this)->region. If NULL then you should redraw the entire window. The undocumented function fl_clip_region(XRegion) will initialize the FLTK clip stack with a region or NULL for no clipping. You must set region to NULL afterwards as fl_clip_region() will own and delete it when done.
If damage() & FL_DAMAGE_EXPOSE then only X expose events have happened. This may be useful if you have an undamaged image (such as a backing buffer) around.
Here is a sample where an undamaged image is kept somewhere:
void MyWindow::flush() {
fl_clip_region(Fl_X::flx(this)->region);
Fl_X::flx(this)->region = 0;
if (damage() != 2) {... draw things into backing store ...}
... copy backing store to window ...
}
Fl_Region fl_clip_region()
Return the current clipping region.
Definition fl_draw.H:206
Note
For compatibility with FLTK versions before 1.4, member function Fl_X::flx(Fl_Window*) can also be written Fl_X::i(Fl_Window*).

virtual void Fl_Window::hide()

Destroy the window server copy of the window. Usually you will destroy contexts, pixmaps, or other resources used by the window, and then call Fl_Window::hide() to get rid of the main window identified by xid(). If you override this, you must also override the destructor as shown:
void MyWindow::hide() {
if (mypixmap) {
XFreePixmap(fl_display,mypixmap);
mypixmap = 0;
}
Fl_Window::hide(); // you must call this
}
void hide() FL_OVERRIDE
Removes the window from the screen.
Definition Fl_Window.cxx:563

virtual void Fl_Window::~Fl_Window()

Because of the way C++ works, if you override hide() you must override the destructor as well (otherwise only the base class hide() is called):
MyWindow::~MyWindow() {
hide();
}
Note
Access to the Fl_X hidden class requires to #define FL_INTERNALS before compilation.

Setting the Icon of a Window

FLTK recommends to set window icons using these platform-independent methods: Fl_Window::icon(const Fl_RGB_Image *) and Fl_Window::icons(const Fl_RGB_Image *[], int). See also methods setting default window icons Fl_Window::default_icon(const Fl_RGB_Image *) and Fl_Window::default_icons(const Fl_RGB_Image *[], int).

FLTK on X11 also supports, for backward compatibility, use of the deprecated method Fl_Window::icon(const void *) as follows :
Sets the icon for the window to the passed pointer. You will need to cast the icon Pixmap to a char* when calling this method. To set a monochrome icon using a bitmap compiled with your application use:

#include "icon.xbm"
fl_open_display(); // needed if display has not been previously opened
Pixmap p = XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_bits, icon_width, icon_height);
window->icon((const void*)p);

To use a multi-colored icon, the XPM format and library should be used as follows:

#include <X11/xpm.h>
#include "icon.xpm"
fl_open_display(); // needed if display has not been previously opened
Pixmap p, mask;
XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display),
icon_xpm, &p, &mask, NULL);
window->icon((const void *)p);

When using the Xpm library, be sure to include it in the list of libraries that are used to link the application (usually "-lXpm").

NOTE:

You must call Fl_Window::show(int argc, char** argv) for the icon to be used. The Fl_Window::show() method does not bind the icon to the window.

Any window icon must be set with the above methods before the window is shown.

X Resources

When the Fl_Window::show(int argc, char** argv) method is called, FLTK looks for the following X resources:

  • background - The default background color for widgets (color).
  • dndTextOps - The default setting for drag and drop text operations (boolean).
  • foreground - The default foreground (label) color for widgets (color).
  • scheme - The default scheme to use (string).
  • selectBackground - The default selection color for menus, etc. (color).
  • Text.background - The default background color for text fields (color).
  • tooltips - The default setting for tooltips (boolean).
  • visibleFocus - The default setting for visible keyboard focus on non-text widgets (boolean).

Resources associated with the first window's Fl_Window::xclass() string are queried first, or if no class has been specified then the class "fltk" is used (e.g. fltk.background). If no match is found, a global search is done (e.g. *background).

Display Scaling Factor

FLTK uses the value of the Xft.dpi resource divided by 96. to initialize the display scaling factor. That is also what is done by the gnome and KDE desktops.

The Windows Interface

Cross-platform applications should bracket Windows-specific source code between #ifdef _WIN32 / #endif.

The Windows interface provides access to the Windows GDI state information and data structures.

Using filenames with non-ASCII characters

In FLTK, all strings, including filenames, are UTF-8 encoded. The utility functions fl_fopen() and fl_open() allow to open files potentially having non-ASCII names in a cross-platform fashion, whereas the standard fopen()/open() functions fail to do so.

Responding to WM_QUIT

FLTK will intercept WM_QUIT messages that are directed towards the thread that runs the main loop. These are converted to SIGTERM signals via raise(). This allows you to deal with outside termination requests with the same code on both Windows and UNIX systems. Other processes can send this message via PostThreadMessage() in order to request, rather than force your application to terminate.

Handling Other Windows API Messages

By default a single WNDCLASSEX called "FLTK" is created. All Fl_Window's are of this class unless you use Fl_Window::xclass(). The window class is created the first time Fl_Window::show() is called.

You can probably combine FLTK with other libraries that make their own window classes. The easiest way is to call Fl::wait(), as it will call DispatchMessage() for all messages to the other windows. If necessary you can let the other library take over as long as it calls DispatchMessage(), but you will have to arrange for the function Fl::flush() to be called regularly so that widgets are updated, timeouts are handled, and the idle functions are called.

extern MSG fl_msg

This variable contains the most recent message read by GetMessage(), which is called by Fl::wait(). This may not be the most recent message sent to an FLTK window, because silly Windows calls the handle procedures directly for some events (sigh).

void Fl::add_handler(int (*f)(int))

Installs a function to parse unrecognized messages sent to FLTK windows. If FLTK cannot figure out what to do with a message, it calls each of these functions (most recent first) until one of them returns non-zero. The argument passed to the functions is the FLTK event that was not handled or zero for unknown messages. If all the handlers return zero then FLTK calls DefWindowProc().

HWND fl_xid(const Fl_Window *)

Returns the window handle for a Fl_Window, or zero if not shown().

Fl_Window *fl_find(HWND xid)

Returns the Fl_Window that corresponds to the given window handle, or NULL if not found. This function uses a cache so it is slightly faster than iterating through the windows yourself.

Drawing Things Using the Windows GDI

When the virtual function Fl_Widget::draw() is called, FLTK stores all the extra arguments you need to make a proper GDI call in some global variables:

extern HINSTANCE fl_display; // for compatibility with previous FLTK versions
extern HINSTANCE fl_win32_display(); // preferred access starting with FLTK 1.4
extern HWND fl_window;
extern HDC fl_gc; // for compatibility with previous FLTK versions
extern HDC fl_win32_gc(); // preferred access starting with FLTK 1.4
COLORREF fl_RGB();
HPEN fl_pen();
HBRUSH fl_brush();
HDC fl_win32_gc()
Returns the Windows-specific graphics context for the current window
HINSTANCE fl_win32_display()
Returns the Windows-specific display in use

These global variables are set before Fl_Widget::draw() is called, or by Fl_Window::make_current(). You can refer to them when needed to produce GDI calls, but don't attempt to change them. The functions return GDI objects for the current color set by fl_color() and are created as needed and cached. A typical GDI drawing call is written like this:

DrawSomething(fl_gc, ..., fl_brush());

It may also be useful to refer to Fl_Window::current() to get the window's size or position.

HighDPI support

FLTK apps for the Windows platform are by default "Per-monitor DPI-aware V2". This means that any window automatically adjusts its physical size in relation to the scaling factor of the display where it maps. This also means that all drawings (e.g., text, lines, images) take advantage of the full resolution of the display in use. FLTK apps may also use the manifest mechanism to declare their level of DPI awareness. The FLTK library adapts to the DPI awareness level set in the app's manifest, which can be lower than the default level if the manifest sets it so.

Display Scaling Factor

FLTK uses the value given by function GetDpiForMonitor() divided by 96. to initialize the scaling factor of each display in the system. This matches the value of "Change the size of text, apps and other items" found in section "System" subsection "Display" of Windows settings.

Setting the Icon of a Window

FLTK recommends to set window icons using these platform-independent methods: Fl_Window::icon(const Fl_RGB_Image *) and Fl_Window::icons(const Fl_RGB_Image *[], int). See also methods setting default window icons Fl_Window::default_icon(const Fl_RGB_Image *) and Fl_Window::default_icons(const Fl_RGB_Image *[], int).

FLTK on Windows also supports, for backward compatibility, use of the deprecated method Fl_Window::icon(const void *) as follows :
Set the icon for the window to the passed pointer. You will need to cast the HICON handle to a char* when calling this method. To set the icon using an icon resource compiled with your application use:

window->icon((const void *)LoadIcon(fl_display, MAKEINTRESOURCE(IDI_ICON)));

You can also use the LoadImage() and related functions to load specific resolutions or create the icon from bitmap data.

NOTE:

You must call Fl_Window::show(int argc, char** argv) for the icon to be used. The Fl_Window::show() method does not bind the icon to the window.

Any window icon must be set with the above methods before the window is shown.

How to Not Get a MSDOS Console Window

Windows has a really stupid mode switch stored in the executables that controls whether or not to make a console window.

To always get a console window you simply create a console application (the "/SUBSYSTEM:CONSOLE" option for the linker). For a GUI-only application create a Windows application (the "/SUBSYSTEM:WINDOWS" option for the linker).

FLTK includes a WinMain() function that calls the ANSI standard main() entry point for you. This function creates a console window when you use the debug version of the library.

Windows applications without a console cannot write to stdout or stderr, even if they are run from a console window. Any output is silently thrown away. Additionally, Windows applications are run in the background by the console, although you can use "start /wait program" to run them in the foreground.

Known Windows Bugs and Problems

The following is a list of known bugs and problems in the Windows version of FLTK:

  • If a program is deactivated, Fl::wait() does not return until it is activated again, even though many events are delivered to the program. This can cause idle background processes to stop unexpectedly. This also happens while the user is dragging or resizing windows or otherwise holding the mouse down. We were forced to remove most of the efficiency FLTK uses for redrawing in order to get windows to update while being moved. This is a design error in Windows and probably impossible to get around.
  • Fl_Gl_Window::can_do_overlay() returns true until the first time it attempts to draw an overlay, and then correctly returns whether or not there is overlay hardware.
  • SetCapture (used by Fl::grab()) doesn't work, and the main window title bar turns gray while menus are popped up.
  • Compilation with gcc 3.4.4 and -Os exposes an optimisation bug in gcc. The symptom is that when drawing filled circles only the perimeter is drawn. This can for instance be seen in the symbols demo. Other optimisation options such as -O2 and -O3 seem to work OK. More details can be found in STR#1656

The Apple OS X Interface

Cross-platform applications should bracket macOS-specific source code between #if defined(__APPLE__) && !defined(FLTK_USE_X11) / #endif.

FLTK supports Apple OS X using the Apple Cocoa library. Older versions of MacOS are no longer supported.

Control, Option, and Command Modifier Keys

FLTK maps the Mac 'control' key to FL_CTRL, the 'option' key to FL_ALT and the 'Apple' key to FL_META. Furthermore, FL_COMMAND designates the 'Apple' key on Mac OS X and the 'control' key on other platforms. Keyboard events return the key name in Fl::event_key() and the keystroke translation in Fl::event_text(). For example, typing Option-Y on a Mac US keyboard will set FL_ALT in Fl::event_state(), set Fl::event_key() to 'y' and return the Yen symbol in Fl::event_text().

Right Click simulation with Ctrl Click

The Apple HIG guidelines indicate applications should support 'Ctrl Click' to simulate 'Right Click' for e.g. context menus, so users with one-button mice and one-click trackpads can still access right-click features. However, paraphrasing Manolo's comment on the fltk.coredev newsgroup:
  • FLTK does /not/ support Ctrl-Click == Right Click itself because Mac OS X event processing doesn't support this at the system level: the system reports left-clicks with the ctrl modifier when the user ctrl-clicks, and OS X system preferences don't allow changing this behavior. Therefore, applications must handle simulation of Right Click with Ctrl Click in the application code.
Ian MacArthur provided the following handle() method code snippet showing an example of how to do this:
case FL_PUSH:
{
int btn = Fl::event_button();
#ifdef __APPLE__
int ev_state = Fl::event_state();
#endif
//
// Context menu can be called up in one of two ways: -
// 1 - right click, as normally used on Windows and Linux
// 2 - Ctrl + left click, as sometimes used on Mac
//
#ifdef __APPLE__
// On apple, check right click, and ctrl+left click
if ((btn == FL_RIGHT_MOUSE) || (ev_state == (FL_CTRL | FL_BUTTON1)))
#else
// On other platforms, only check right click as ctrl+left is used for selections
if (btn == FL_RIGHT_MOUSE)
#endif
{
// Did we right click on the object?..
#define FL_CTRL
One of the ctrl keys is down.
Definition Enumerations.H:569
#define FL_RIGHT_MOUSE
The right mouse button.
Definition Enumerations.H:552
@ FL_PUSH
A mouse button has gone down with the mouse pointing at this widget.
Definition Enumerations.H:211
#define FL_BUTTON1
Mouse button 1 is pushed.
Definition Enumerations.H:577
static int event_button()
Gets which particular mouse button caused the current event.
Definition Fl.H:697
static int event_state()
Returns the keyboard and mouse button states of the last event.
Definition Fl.H:723
There is a thread about this subject on fltk.coredev (Aug 1-14, 2014) entitled "[RFC] Right click emulation for one button mouse on Mac".

Apple "Quit" Event

When the user presses Cmd-Q or requests a termination of the application, FLTK sends an FL_CLOSE event to all open windows. If any window remains open, the termination request aborts. If all windows close, the application's event loop terminates, that is, Fl::run() returns. The application can then follow FLTK's normal termination path executing cleanup code that may be programmed after termination of the event loop, and returning from main(). Function Fl::program_should_quit() allows to detect whether the event loop terminated because of a program termination request.

Apple "Open" Event

Whenever the user drops a file onto an application icon, OS X generates an Apple Event of the type "Open". You can have FLTK notify you of an Open event by calling the fl_open_callback() function.

void fl_open_display()

Opens the display. Does nothing if it is already open. You should call this if you wish to do Cocoa or Quartz calls and there is a chance that your code will be called before the first show() of a window.

Window fl_xid(const Fl_Window *)

Returns the window reference for an Fl_Window, or NULL if the window has not been shown. This reference is a pointer to an instance of the subclass FLWindow of Cocoa's NSWindow class.

Fl_Window *fl_find(Window xid)

Returns the Fl_Window that corresponds to the given window reference, or NULL if not found.

void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut)

Attaches the callback cb to the "About myprog" item of the system application menu. cb will be called with NULL first argument and user_data second argument. This MacOS-specific function is deprecated in FLTK 1.4 and replaced by Fl_Sys_Menu_Bar::about(Fl_Callback *cb, void *data) which is cross-platform.

Fl_Sys_Menu_Bar class

The Fl_Sys_Menu_Bar class allows to build menu bars that, on Mac OS X, are placed in the system menu bar (at top-left of display), and, on other platforms, at a user-chosen location of a user-chosen window.

Setting the icon of an application

  • First, create a .icns file containing several copies of your icon of decreasing sizes. This can be done using the Preview application or the Icon Composer application available in "Graphics Tools for Xcode". To create a high resolution icon file, it is necessary to use the iconutil command-line utility.
  • Put your .icns file in the Resources subdirectory of your application bundle.
  • Add these two lines to the Info.plist file of your application bundle
    <key>CFBundleIconFile</key>
    <string>foo.icns</string>
    
    replacing foo by your application name. If you use Xcode, just add your .icns file to your application target.

Drawing Things Using Quartz

All code inside Fl_Widget::draw() is expected to call Quartz drawing functions. The Quartz coordinate system is flipped to match FLTK's coordinate system. The origin for all drawing is in the top left corner of the enclosing Fl_Window. The function fl_mac_gc() returns the appropriate Quartz 2D drawing environment (of type CGContextRef). For compatibility with previous FLTK versions, deprecated global variable fl_gc gives the same value.

Include FL/platform.H to declare the fl_mac_gc() function (or the fl_gc variable).

Internationalization

All FLTK programs contain an application menu with, e.g., the About xxx, Hide xxx, and Quit xxx items. This menu can be internationalized/localized by any of two means.

  • using the Fl_Mac_App_Menu class.
  • using the standard Mac OS X localization procedure. Create a language-specific .lproj directory (e.g., German.lproj) in the Resources subdirectory of the application bundle. Create therein a Localizable.strings file that translates all menu items to this language. The German Localizable.strings file, for example, contains:
    "About %@" = "Über %@";
    "Print Front Window"="Frontfenster drucken";
    "Services" = "Dienste";
    "Hide %@"="%@ ausblenden";
    "Hide Others"="Andere ausblenden";
    "Show All"="Alle einblenden";
    "Quit %@"="%@ beenden";
    
    Set "Print Front Window" = ""; therein so the application menu doesn't show a "Print Front Window" item. To localize the application name itself, create a file InfoPlist.strings in each .lproj directory and put CFBundleName = "localized name"; in each such file.

OpenGL and 'retina' displays

It is possible to have OpenGL produce graphics at the high pixel resolution allowed by the so-called 'retina' displays present on recent Apple hardware. For this, call

Fl::use_high_res_GL(1);

before any Fl_Gl_Window is shown. Also, adapt your Fl_Gl_Window::draw() and Fl_Gl_Window::draw_overlay() methods replacing

glViewport(0, 0, w(), h());

by

glViewport(0, 0, pixel_w(), pixel_h());

making use of the Fl_Gl_Window::pixel_w() and Fl_Gl_Window::pixel_h() methods that return the width and height of the GL scene in pixels: if the Fl_Gl_Window is mapped on a retina display, these methods return twice as much as reported by Fl_Widget::w() and Fl_Widget::h(); if it's mapped on a regular display, they return the same values as w() and h(). These methods dynamically change their values if the window is moved into/out from a retina display. If Fl::use_high_res_GL(1) is not called, all Fl_Gl_Window 's are drawn at low resolution. These methods are useful on all platforms because Fl_Gl_Window::w() and Fl_Gl_Window::h() don't return, on HighDPI displays, the quantitites in pixels necessary to OpenGL functions .

The Fl_Gl_Window::pixels_per_unit() method is useful when the OpenGL code depends on the pixel dimension of the GL scene. This occurs, e.g., if a window's handle() method uses Fl::event_x() and Fl::event_y() whose returned values should be multiplied by Fl_Gl_Window::pixels_per_unit() to obtain the adequate pixel units. This method may also be useful, for example, to adjust the width of a line in a high resolution GL scene.

Fl_Double_Window

OS X double-buffers all windows automatically. On OS X, Fl_Window and Fl_Double_Window are handled internally in the same way.

Mac File System Specifics

Resource Forks

FLTK does not access the resource fork of an application. However, a minimal resource fork must be created for OS X applications. Starting with OS X 10.6, resource forks are no longer needed.

Caution (OS X 10.2 and older):

When using UNIX commands to copy or move executables, OS X will NOT copy any resource forks! For copying and moving use CpMac and MvMac respectively. For creating a tar archive, all executables need to be stripped from their Resource Fork before packing, e.g. "DeRez fluid > fluid.r". After unpacking the Resource Fork needs to be reattached, e.g. "Rez fluid.r -o fluid".

It is advisable to use the Finder for moving and copying and Mac archiving tools like Sit for distribution as they will handle the Resource Fork correctly.

Mac File Paths

FLTK uses UTF-8-encoded UNIX-style filenames and paths.

See also
Mac OS X-specific symbols

The Wayland Interface

Cross-platform applications should bracket Wayland-specific source code between #ifdef FLTK_USE_WAYLAND / #endif and should ensure function fl_wl_display() returns non-NULL before calling Wayland-specific functions and using Wayland-specific symbols.

extern struct wl_display *fl_wl_display();

After fl_open_display() has run, function fl_wl_display() returns a pointer to the struct wl_display representing the connection between the application and Wayland. For example, wl_display_get_fd(fl_wl_display()) gives the file descriptor one can use to communicate with the Wayland compositor according to the Wayland protocol.

struct wld_window *fl_wl_xid(const Fl_Window *)

Returns a pointer to an FLTK-defined structure holding Wayland-related data created when a window gets show()'n, or NULL if not show()'n.

Fl_Window *fl_wl_find(struct wld_window * wld_win)

Returns the Fl_Window that corresponds to the given Window, or NULL if not found.

struct wl_surface *fl_wl_surface(struct wld_window *wld_win)

Returns a pointer to the struct wl_surface corresponding to a show()'n top-level window or subwindow.

cairo_t *fl_wl_gc()

Drawing natively to a Wayland window : Within an overridden Fl_Widget::draw() method, or after a call to Fl_Window::make_current(), it's possible to draw using the Cairo library. Function fl_wl_gc() returns the adequate cairo_t* value. Regular FLTK coordinates, with top-left origin, are to be used. All FLTK-defined drawing functions (e.g., fl_rect(), fl_draw()) can be used too.

void fl_close_display()

This closes the Wayland connection. You do not need to call this to exit. It may be useful to call this if you want your program to continue without the Wayland connection. You cannot open the display again, and cannot call any FLTK functions.
See also
wayland.H for all functions specific of the Wayland platform.

HiDPI display support

FLTK Wayland apps automatically scale according to the Wayland-defined, integer-valued scale factor. On a HiDPI display, it's enough to set this factor to 2 for any FLTK app to be drawn using twice as many pixels and thus to be as readable as it is on a regular display. With the gnome and KDE-plasma desktops, that is achieved in the "Displays" section of the "Settings" application, selecting 200 % for the "Scale" parameter. In addition to this, FLTK apps can also be scaled up or down typing ctrl/+/-/0/ and with the FLTK_SCALING_FACTOR environment variable.

Window icons

Standard FLTK functions Fl_Window::icon(const Fl_RGB_Image*), Fl_Window::icons(const Fl_RGB_Image*[], int), Fl_Window::default_icon(const Fl_RGB_Image*) and Fl_Window::default_icons(const Fl_RGB_Image*[], int) have no effect on the Wayland platform. The equivalent of a call to Fl_Window::default_icon(const Fl_RGB_Image*) to set the application-specific window icon can be obtained as follows, using FLTK's editor app as an example:

  • create a text file named editor.desktop containing :
    [Desktop Entry]
    Version=1.0
    Type=Application
    Name=Editor
    Name[fr]=Editeur
    Comment=FLTK editor
    Exec=editor %F
    Icon=/path/to/icon/file/editor.svg
    MimeType=text/plain
    
  • The Name= line therein determines the string displayed when the app runs.
  • Optionally, one or more Name[locale]= lines can be used to set locale-specific app names.
  • The Icon= line accepts also .png files.
  • Put this file in /usr/local/share/applications/ so it's available to all system users or in $HOME/.local/share/applications/ so it's available to a single user.

Window titlebars

Wayland supports both client-side window decoration (CSD), where client applications are responsible for drawing window titlebars, and server-side window decoration (SSD), where the Wayland compositor itself draws window titlebars. Among 4 tested Wayland compositors, Mutter (gnome's compositor) and Weston use CSD mode whereas the KWin and Sway compositors use SSD mode. When running in CSD mode, FLTK uses a library called libdecor to draw titlebars. The libdecor library has been conceived to use various plug-in's to draw titlebars in various fashions intended to match any desktop's preferred titlebar style. FLTK supports drawing titlebars with any libdecor plug-in via an environment variable called LIBDECOR_PLUGIN_DIR which can be given the name of a directory containing the desired plug-in. When LIBDECOR_PLUGIN_DIR is not defined, or points to a directory that doesn't contain a libdecor plug-in, FLTK uses its built-in plug-in to draw titlebars. That is the most common situation, until libdecor plug-in's become available for popular UNIX desktops.


[Prev] Forms Compatibility [Index] Migrating Code from FLTK 1.3 to 1.4 [Next]