Implemented wxToplevelWindowMotif. (forgot to commit)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18604 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
7563339557
commit
0de6dfa701
81
include/wx/motif/toplevel.h
Normal file
81
include/wx/motif/toplevel.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/motif/toplevel.h
|
||||||
|
// Purpose: wxTopLevelWindow Motif implementation
|
||||||
|
// Author: Mattia Barbon
|
||||||
|
// Modified by:
|
||||||
|
// Created: 12/10/2002
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Mattia Barbon
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef __MOTIFTOPLEVELH__
|
||||||
|
#define __MOTIFTOPLEVELH__
|
||||||
|
|
||||||
|
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||||
|
#pragma interface "toplevel.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class wxTopLevelWindowMotif : public wxTopLevelWindowBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxTopLevelWindowMotif() { Init(); }
|
||||||
|
wxTopLevelWindowMotif( wxWindow* parent, wxWindowID id,
|
||||||
|
const wxString& title,
|
||||||
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
|
const wxSize& size = wxDefaultSize,
|
||||||
|
long style = wxDEFAULT_FRAME_STYLE,
|
||||||
|
const wxString& name = wxFrameNameStr )
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
|
||||||
|
Create( parent, id, title, pos, size, style, name );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Create( wxWindow* parent, wxWindowID id,
|
||||||
|
const wxString& title,
|
||||||
|
const wxPoint& pos = wxDefaultPosition,
|
||||||
|
const wxSize& size = wxDefaultSize,
|
||||||
|
long style = wxDEFAULT_FRAME_STYLE,
|
||||||
|
const wxString& name = wxFrameNameStr );
|
||||||
|
|
||||||
|
virtual ~wxTopLevelWindowMotif();
|
||||||
|
|
||||||
|
virtual bool ShowFullScreen( bool show, long style = wxFULLSCREEN_ALL );
|
||||||
|
virtual bool IsFullScreen() const;
|
||||||
|
|
||||||
|
virtual void Maximize(bool maximize = TRUE);
|
||||||
|
virtual void Restore();
|
||||||
|
virtual void Iconize(bool iconize = TRUE);
|
||||||
|
virtual bool IsMaximized() const;
|
||||||
|
virtual bool IsIconized() const;
|
||||||
|
|
||||||
|
virtual void Raise();
|
||||||
|
virtual void Lower();
|
||||||
|
|
||||||
|
virtual wxString GetTitle() const { return m_title; }
|
||||||
|
virtual void SetTitle( const wxString& title ) { m_title = title; }
|
||||||
|
|
||||||
|
WXWidget GetShellWidget() const;
|
||||||
|
protected:
|
||||||
|
// common part of all constructors
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// both these functions should be pure virtual
|
||||||
|
virtual bool DoCreate( wxWindow* parent, wxWindowID id,
|
||||||
|
const wxString& title,
|
||||||
|
const wxPoint& pos,
|
||||||
|
const wxSize& size,
|
||||||
|
long style,
|
||||||
|
const wxString& name )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DoDestroy() { }
|
||||||
|
|
||||||
|
wxString m_title;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __MOTIFTOPLEVELH__
|
385
src/motif/toplevel.cpp
Normal file
385
src/motif/toplevel.cpp
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: motif/toplevel.cpp
|
||||||
|
// Purpose: wxTopLevelWindow Motif implementation
|
||||||
|
// Author: Mattia Barbon
|
||||||
|
// Modified by:
|
||||||
|
// Created: 12/10/2002
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Mattia Barbon
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(__GNUG__) && !defined(__APPLE__)
|
||||||
|
#pragma implementation "toplevel.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/toplevel.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
|
||||||
|
#ifdef __VMS__
|
||||||
|
#pragma message disable nosimpint
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Xm/Xm.h>
|
||||||
|
#include <X11/Shell.h>
|
||||||
|
#include <X11/Core.h>
|
||||||
|
#if XmVersion >= 1002
|
||||||
|
#include <Xm/XmAll.h>
|
||||||
|
#else
|
||||||
|
#include <Xm/Frame.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __VMS__
|
||||||
|
#pragma message enable nosimpint
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/motif/private.h"
|
||||||
|
|
||||||
|
wxList wxModelessWindows; // Frames and modeless dialogs
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Callbacks
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void wxCloseTLWCallback( Widget widget, XtPointer client_data,
|
||||||
|
XmAnyCallbackStruct *cbs );
|
||||||
|
static void wxTLWEventHandler( Widget wid,
|
||||||
|
XtPointer client_data,
|
||||||
|
XEvent* event,
|
||||||
|
Boolean *continueToDispatch );
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// wxTopLevelWindowMotif implementation
|
||||||
|
// ===========================================================================
|
||||||
|
|
||||||
|
wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
|
||||||
|
{
|
||||||
|
wxTopLevelWindows.DeleteObject(this);
|
||||||
|
|
||||||
|
if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
|
||||||
|
wxModelessWindows.DeleteObject(this);
|
||||||
|
|
||||||
|
m_icons.m_icons.Empty();
|
||||||
|
|
||||||
|
DestroyChildren();
|
||||||
|
|
||||||
|
// MessageDialog and FileDialog do not have a client widget
|
||||||
|
if( GetClientWidget() )
|
||||||
|
{
|
||||||
|
XtRemoveEventHandler( (Widget)GetClientWidget(),
|
||||||
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
|
PointerMotionMask | KeyPressMask,
|
||||||
|
FALSE,
|
||||||
|
wxTLWEventHandler,
|
||||||
|
(XtPointer)this );
|
||||||
|
}
|
||||||
|
|
||||||
|
DoDestroy();
|
||||||
|
|
||||||
|
SetMainWidget( (WXWidget)0 );
|
||||||
|
|
||||||
|
// If this is the last top-level window, exit.
|
||||||
|
if (wxTheApp && (wxTopLevelWindows.Number() == 0))
|
||||||
|
{
|
||||||
|
wxTheApp->SetTopWindow(NULL);
|
||||||
|
|
||||||
|
if (wxTheApp->GetExitOnFrameDelete())
|
||||||
|
{
|
||||||
|
wxTheApp->ExitMainLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowMotif::Init()
|
||||||
|
{
|
||||||
|
m_isShown = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowMotif::Create( wxWindow *parent, wxWindowID id,
|
||||||
|
const wxString& title,
|
||||||
|
const wxPoint& pos,
|
||||||
|
const wxSize& size,
|
||||||
|
long style,
|
||||||
|
const wxString& name )
|
||||||
|
{
|
||||||
|
SetName(name);
|
||||||
|
m_windowStyle = style;
|
||||||
|
|
||||||
|
if ( parent )
|
||||||
|
parent->AddChild(this);
|
||||||
|
|
||||||
|
wxTopLevelWindows.Append(this);
|
||||||
|
|
||||||
|
m_windowId = ( id > -1 ) ? id : NewControlId();
|
||||||
|
|
||||||
|
bool retval = DoCreate( parent, id, title, pos, size, style, name );
|
||||||
|
|
||||||
|
if( !retval ) return FALSE;
|
||||||
|
|
||||||
|
// Intercept CLOSE messages from the window manager
|
||||||
|
Widget shell = (Widget)GetShellWidget();
|
||||||
|
Atom WM_DELETE_WINDOW = XmInternAtom( XtDisplay( shell ),
|
||||||
|
"WM_DELETE_WINDOW", False );
|
||||||
|
|
||||||
|
// Remove and add WM_DELETE_WINDOW so ours is only handler
|
||||||
|
// This only appears to be necessary for wxDialog, but does not hurt
|
||||||
|
// for wxFrame
|
||||||
|
XmRemoveWMProtocols( shell, &WM_DELETE_WINDOW, 1 );
|
||||||
|
XmAddWMProtocols( shell, &WM_DELETE_WINDOW, 1 );
|
||||||
|
XmActivateWMProtocol( shell, WM_DELETE_WINDOW );
|
||||||
|
|
||||||
|
// Modified Steve Hammes for Motif 2.0
|
||||||
|
#if (XmREVISION > 1 || XmVERSION > 1)
|
||||||
|
XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
|
||||||
|
(XtCallbackProc)wxCloseTLWCallback,
|
||||||
|
(XtPointer)this );
|
||||||
|
#elif XmREVISION == 1
|
||||||
|
XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
|
||||||
|
(XtCallbackProc)wxCloseTLWCallback,
|
||||||
|
(caddr_t)this );
|
||||||
|
#else
|
||||||
|
XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
|
||||||
|
(void (*)())wxCloseTLWCallback, (caddr_t)this );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This patch come from Torsten Liermann lier@lier1.muc.de
|
||||||
|
if( XmIsMotifWMRunning( shell ) )
|
||||||
|
{
|
||||||
|
int decor = 0 ;
|
||||||
|
if( m_windowStyle & wxRESIZE_BORDER )
|
||||||
|
decor |= MWM_DECOR_RESIZEH;
|
||||||
|
if( m_windowStyle & wxSYSTEM_MENU )
|
||||||
|
decor |= MWM_DECOR_MENU;
|
||||||
|
if( ( m_windowStyle & wxCAPTION ) ||
|
||||||
|
( m_windowStyle & wxTINY_CAPTION_HORIZ ) ||
|
||||||
|
( m_windowStyle & wxTINY_CAPTION_VERT ) )
|
||||||
|
decor |= MWM_DECOR_TITLE;
|
||||||
|
if( m_windowStyle & wxTHICK_FRAME )
|
||||||
|
decor |= MWM_DECOR_BORDER;
|
||||||
|
if( m_windowStyle & wxMINIMIZE_BOX )
|
||||||
|
decor |= MWM_DECOR_MINIMIZE;
|
||||||
|
if( m_windowStyle & wxMAXIMIZE_BOX )
|
||||||
|
decor |= MWM_DECOR_MAXIMIZE;
|
||||||
|
|
||||||
|
XtVaSetValues( shell,
|
||||||
|
XmNmwmDecorations, decor,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This allows non-Motif window managers to support at least the
|
||||||
|
// no-decorations case.
|
||||||
|
if( ( m_windowStyle & wxCAPTION ) != wxCAPTION )
|
||||||
|
XtVaSetValues( shell,
|
||||||
|
XmNoverrideRedirect, TRUE,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
XtAddEventHandler( (Widget)GetClientWidget(),
|
||||||
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
|
PointerMotionMask | KeyPressMask,
|
||||||
|
FALSE,
|
||||||
|
wxTLWEventHandler,
|
||||||
|
(XtPointer)this );
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowMotif::Raise()
|
||||||
|
{
|
||||||
|
Widget top = (Widget) GetTopWidget();
|
||||||
|
Window parent_window = XtWindow( top ),
|
||||||
|
next_parent = XtWindow( top ),
|
||||||
|
root = RootWindowOfScreen( XtScreen( top ) );
|
||||||
|
// search for the parent that is child of ROOT, because the WM may
|
||||||
|
// reparent twice and notify only the next parent (like FVWM)
|
||||||
|
while( next_parent != root )
|
||||||
|
{
|
||||||
|
Window *theChildren;
|
||||||
|
unsigned int n;
|
||||||
|
|
||||||
|
parent_window = next_parent;
|
||||||
|
XQueryTree( XtDisplay( top ), parent_window, &root,
|
||||||
|
&next_parent, &theChildren, &n );
|
||||||
|
XFree( theChildren ); // not needed
|
||||||
|
}
|
||||||
|
XRaiseWindow( XtDisplay( top ), parent_window );
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowMotif::Lower()
|
||||||
|
{
|
||||||
|
Widget top = (Widget) GetTopWidget();
|
||||||
|
Window parent_window = XtWindow( top ),
|
||||||
|
next_parent = XtWindow( top ),
|
||||||
|
root = RootWindowOfScreen( XtScreen( top ) );
|
||||||
|
// search for the parent that is child of ROOT, because the WM may
|
||||||
|
// reparent twice and notify only the next parent (like FVWM)
|
||||||
|
while( next_parent != root )
|
||||||
|
{
|
||||||
|
Window *theChildren;
|
||||||
|
unsigned int n;
|
||||||
|
|
||||||
|
parent_window = next_parent;
|
||||||
|
XQueryTree( XtDisplay( top ), parent_window, &root,
|
||||||
|
&next_parent, &theChildren, &n );
|
||||||
|
XFree( theChildren ); // not needed
|
||||||
|
}
|
||||||
|
XLowerWindow( XtDisplay( top ), parent_window );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Widget GetShell( const wxTopLevelWindowMotif* tlw )
|
||||||
|
{
|
||||||
|
Widget main = (Widget) tlw->GetMainWidget();
|
||||||
|
if( !main ) return (Widget) NULL;
|
||||||
|
|
||||||
|
return XtParent( main );
|
||||||
|
}
|
||||||
|
|
||||||
|
WXWidget wxTopLevelWindowMotif::GetShellWidget() const
|
||||||
|
{
|
||||||
|
return (WXWidget) GetShell( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowMotif::ShowFullScreen( bool show,
|
||||||
|
long style = wxFULLSCREEN_ALL )
|
||||||
|
{
|
||||||
|
// TODO, see wxGTK
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowMotif::IsFullScreen() const
|
||||||
|
{
|
||||||
|
// TODO, see wxGTK
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowMotif::Restore()
|
||||||
|
{
|
||||||
|
Widget shell = GetShell( this );
|
||||||
|
|
||||||
|
if( shell )
|
||||||
|
XtVaSetValues( shell,
|
||||||
|
XmNiconic, FALSE,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowMotif::Iconize( bool iconize = TRUE )
|
||||||
|
{
|
||||||
|
Widget shell = GetShell( this );
|
||||||
|
if( !shell ) return;
|
||||||
|
|
||||||
|
if( !iconize )
|
||||||
|
Show( TRUE );
|
||||||
|
|
||||||
|
XtVaSetValues( shell,
|
||||||
|
XmNiconic, (Boolean)iconize,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowMotif::IsIconized() const
|
||||||
|
{
|
||||||
|
Widget shell = GetShell( this );
|
||||||
|
|
||||||
|
if( !shell )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
Boolean iconic;
|
||||||
|
XtVaGetValues( shell,
|
||||||
|
XmNiconic, &iconic,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
return iconic;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowMotif::Maximize( bool maximize = TRUE )
|
||||||
|
{
|
||||||
|
Show( TRUE );
|
||||||
|
|
||||||
|
if( maximize )
|
||||||
|
Restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowMotif::IsMaximized() const
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Callback definition
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Handle a close event from the window manager
|
||||||
|
static void wxCloseTLWCallback( Widget WXUNUSED(widget), XtPointer client_data,
|
||||||
|
XmAnyCallbackStruct *WXUNUSED(cbs) )
|
||||||
|
{
|
||||||
|
wxTopLevelWindowMotif* tlw = (wxTopLevelWindowMotif*)client_data;
|
||||||
|
wxCloseEvent closeEvent( wxEVT_CLOSE_WINDOW, tlw->GetId() );
|
||||||
|
closeEvent.SetEventObject( tlw );
|
||||||
|
|
||||||
|
// May delete the dialog (with delayed deletion)
|
||||||
|
tlw->GetEventHandler()->ProcessEvent(closeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxTLWEventHandler( Widget wid,
|
||||||
|
XtPointer WXUNUSED(client_data),
|
||||||
|
XEvent* event,
|
||||||
|
Boolean* continueToDispatch)
|
||||||
|
{
|
||||||
|
wxTopLevelWindowMotif* tlw =
|
||||||
|
(wxTopLevelWindowMotif*)wxGetWindowFromTable( wid );
|
||||||
|
|
||||||
|
if( tlw )
|
||||||
|
{
|
||||||
|
wxMouseEvent wxevent( wxEVT_NULL );
|
||||||
|
|
||||||
|
if( wxTranslateMouseEvent( wxevent, tlw, wid, event ) )
|
||||||
|
{
|
||||||
|
wxevent.SetEventObject( tlw );
|
||||||
|
wxevent.SetId( tlw->GetId() );
|
||||||
|
tlw->GetEventHandler()->ProcessEvent( wxevent );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// An attempt to implement OnCharHook by calling OnCharHook first;
|
||||||
|
// if this returns TRUE, set continueToDispatch to False
|
||||||
|
// (don't continue processing).
|
||||||
|
// Otherwise set it to True and call OnChar.
|
||||||
|
wxKeyEvent keyEvent( wxEVT_CHAR );
|
||||||
|
if( wxTranslateKeyEvent( keyEvent, tlw, wid, event ))
|
||||||
|
{
|
||||||
|
keyEvent.SetEventObject( tlw );
|
||||||
|
keyEvent.SetId( tlw->GetId() );
|
||||||
|
keyEvent.SetEventType( wxEVT_CHAR_HOOK );
|
||||||
|
if( tlw->GetEventHandler()->ProcessEvent( keyEvent ) )
|
||||||
|
{
|
||||||
|
*continueToDispatch = False;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For simplicity, OnKeyDown is the same as OnChar
|
||||||
|
// TODO: filter modifier key presses from OnChar
|
||||||
|
keyEvent.SetEventType( wxEVT_KEY_DOWN );
|
||||||
|
|
||||||
|
// Only process OnChar if OnKeyDown didn't swallow it
|
||||||
|
if( !tlw->GetEventHandler()->ProcessEvent( keyEvent ) )
|
||||||
|
{
|
||||||
|
keyEvent.SetEventType( wxEVT_CHAR );
|
||||||
|
tlw->GetEventHandler()->ProcessEvent( keyEvent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*continueToDispatch = True;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user