Sometimes you'll need to interact with the Photon Window Manager to make your windows and dialogs behave the way you'd like.
This chapter discusses:
Remember that PhAB's window and dialog modules are implemented as PtWindow widgets. PtWindow has many resources that are used to interact with the Window Manager. |
For information about the Window Manager's regions, see the appendix on Photon architecture. For a list of related functions, see "Window Manager" in the Summary of Functions chapter of the Photon Library Reference.
The PtWindow widget defines various types of flags:
If you change the state of the window after it's realized, you'll need to let the Window Manager know. See "Getting and setting the window state" later in this chapter. |
The Pt_ARG_WINDOW_RENDER_FLAGS resource specifies what appears in the window's frame:
To display: | Set this bit: | Default: |
---|---|---|
Border | Ph_WM_RENDER_BORDER | Yes |
Resize handles | Ph_WM_RENDER_RESIZE | Yes |
Title bar | Ph_WM_RENDER_TITLE | Yes |
Menu button | Ph_WM_RENDER_MENU | Yes |
Close button | Ph_WM_RENDER_CLOSE | |
Help button (question mark) | Ph_WM_RENDER_HELP | |
Minimize button | Ph_WM_RENDER_MIN | Yes |
Maximize button | Ph_WM_RENDER_MAX | Yes |
Using these flags to display a decoration doesn't cause the Window Manager to do anything with it. You may need to set the window managed flags and/or notify flags. |
The Pt_ARG_WINDOW_MANAGED_FLAGS resource specifies what operations you want the window manager to handle:
To let the window manager: | Set this bit: | Default: |
---|---|---|
Close the window | Ph_WM_CLOSE | Yes |
Give focus | Ph_WM_FOCUS | Yes |
Build and control the window menu | Ph_WM_MENU | Yes |
Move the window to the front | Ph_WM_TOFRONT | Yes |
Move the window to the back | Ph_WM_TOBACK | Yes |
Move the window to a new console as the user switches consoles | Ph_WM_CONSWITCH | |
Resize the window | Ph_WM_RESIZE | Yes |
Move the window | Ph_WM_MOVE | Yes |
Hide (i.e. minimize) the window | Ph_WM_HIDE | Yes |
Maximize the window | Ph_WM_MAX | Yes |
Display the window as a backdrop | Ph_WM_BACKDROP | |
Restore the window | Ph_WM_RESTORE | Yes |
Provide context-sensitive help | Ph_WM_HELP | |
Make the window force-front | Ph_WM_FFRONT |
By default, a selection of these flags are set, as defined by Ph_WM_APP_DEF_MANAGED in <PhWm.h>. You'd turn the management flags off if:
The Pt_ARG_WINDOW_NOTIFY_FLAGS resource specifies which window-manager operations your application should be notified of. This resource uses the same bits as Pt_ARG_WINDOW_MANAGED_FLAGS:
To be notified when: | Set this bit: | Default: |
---|---|---|
The window is to be closed (see below) | Ph_WM_CLOSE | Yes |
The window is to gain/lose focus | Ph_WM_FOCUS | |
The window menu is requested or dismissed | Ph_WM_MENU | |
The window is to be moved to the front | Ph_WM_TOFRONT | |
The window is to be moved to the back | Ph_WM_TOBACK | |
The window is to switch consoles | Ph_WM_CONSWITCH | |
The window is to be resized | Ph_WM_RESIZE | Yes |
The window is to be moved | Ph_WM_MOVE | |
The window is to be hidden or unhidden | Ph_WM_HIDE | |
The window is to be maximized | Ph_WM_MAX | |
The window is to be made into a backdrop | Ph_WM_BACKDROP | |
The window is to be restored | Ph_WM_RESTORE | |
The help button is pressed | Ph_WM_HELP | Yes |
The window is to be made force-front or not force-front | Ph_WM_FFRONT |
The default setting is Ph_WM_RESIZE|Ph_WM_CLOSE| Ph_WM_HELP.
When the requested operations occur, the window's Pt_CB_WINDOW callback is invoked. See "Notification callback" below.
If you set the Ph_WM_CLOSE notify flag, your application's Pt_CB_WINDOW callback is invoked when someone wants the window to close. Your application doesn't have to close the window - it could decide to leave it open.
In contrast, the Pt_CB_WINDOW_CLOSING callback is called when a window is being unrealized, but before its region is removed. At this point, the application can't stop the window from being closed.
If you've set the Ph_WM_CLOSE managed flag, the window manager is told to handle the window's closing. In this case, the Pt_CB_WINDOW_CLOSING callback is invoked, but the Pt_CB_WINDOW callback isn't. |
When a window manager operation occurs that's listed in the window's notify flags (Pt_ARG_WINDOW_NOTIFY_FLAGS), the window's Pt_CB_WINDOW callback is invoked.
Each callback function listed in this resource is passed a PtCallbackInfo_t structure that contains at least the following members:
These callback functions should return Pt_CONTINUE.
Suppose you want to verify that the user really wants to exit the application when the window is closed. Here's what you need to do:
int window_callback( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) { PhWindowEvent_t *we = cbinfo->cbdata; /* eliminate 'unreferenced' warnings */ widget = widget, apinfo = apinfo, cbinfo = cbinfo; if ( we->event_f == Ph_WM_CLOSE ) { // Ask the user if we should really exit. switch( PtAskQuestion( ABW_base, NULL, "Do you really want to exit?", "helv14", "&Yes", "&No", NULL, 1 ) ) { case 1: /* yes */ exit (EXIT_SUCCESS); break; case 2: /* no */ return (Pt_CONTINUE); } } else { // Check for other events } return( Pt_CONTINUE ); }
There's a significant difference between the Ph_WM_CLOSE event and the Window Closing (Pt_CB_WINDOW_CLOSING) callback.
A Pt_CB_WINDOW callback with a Ph_WM_CLOSE event is just a notification from PWM that the user has clicked on the Close button or chosen Close from the PWM menu. If the Ph_WM_CLOSE bit is unset in the Pt_ARG_WINDOW_MANAGED_FLAGS, the library takes no further action.
Window Closing is invoked when the window is about to unrealize for any reason. This includes transporting to another Photon and explicit calls to PtDestroyWidget() or PtUnrealizeWidget(). If you want to make sure in a Window Closing callback that the window is actually being destroyed, check the Pt_DESTROYED flag in Pt_ARG_FLAGS. You can also use the Pt_CB_DESTROYED callback to know when a window is marked for destruction.
Also note that calling exit() explicitly bypasses all those callbacks.
The Pt_ARG_WINDOW_STATE resource controls what state the window will be in when it's realized:
To do this: | Set this bit: |
---|---|
Maximize the window | Ph_WM_STATE_ISMAX |
Make the window a backdrop | Ph_WM_STATE_ISBACKDROP |
Minimize the window | Ph_WM_STATE_ISHIDDEN |
Place the base window in front of the windows of all other applications | Ph_WM_STATE_ISFRONT |
Give keyboard focus to the window if cursor focus is disabled | Ph_WM_STATE_ISFOCUS |
Pass Alt key combinations to the application | Ph_WM_STATE_ISALTKEY |
Block the window | Ph_WM_STATE_ISBLOCKED (read-only) |
The default value is Ph_WM_STATE_ISFOCUS.
You can get the state of the window at any time by using PtGetResources() to get the Pt_ARG_WINDOW_STATE resource.
You can use this resource to set the window state before a window is realized. For example, you could set it when creating the PtWindow widget or in the window's Pt_CB_WINDOW_OPENING callback. The setting will be in effect when the window is realized. To set the window state after it's open, you'll need to let the window manager know by calling:
For example, to minimize a window that belongs to your application and is already open:
PhWindowEvent_t event; memset( &event, 0, sizeof (event) ); event.event_f = Ph_WM_HIDE; event.event_state = Ph_WM_EVSTATE_HIDE; event.rid = PtWidgetRid( window ); PtForwardWindowEvent( &event );
To minimize a window that belongs to another application and is already open:
PhWindowEvent_t event; memset( &event, 0, sizeof (event) ); event.event_f = Ph_WM_HIDE; event.event_state = Ph_WM_EVSTATE_HIDE; PtForwardWindowTaskEvent( processid, &event );
When you call these functions, you're asking the window manager to do the specified action. If the action isn't set in the managed flags (Pt_ARG_WINDOW_MANAGED_FLAGS) for the given window, the window manager doesn't do it. |
If your application has more than one window, you'll need to take the relationships between them into account.
By definition, a child window is always in front of its parent. The child windows can move above and below siblings. For windows to be able to go behind other windows, they must be siblings. So for a window to be able to move behind the base window, that window would have to have no parent.
The following low-level functions are associated with the window manager, but shouldn't be used in an application that uses widgets:
These functions can be called in an application that uses widgets:
If your application is intended to run by itself, you might want to:
For information on starting your application automatically, see "Booting directly into Photon" in the Configuring Photon chapter of the Photon Installation & Configuration guide.