Implemented two-window approach for wxX11.

Implemented wxSTAY_ON_TOP the way Qt does it.
  Added group window support.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14764 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2002-03-24 22:17:53 +00:00
parent df0e1b64e3
commit ab6b6b15e0
11 changed files with 462 additions and 314 deletions

View File

@@ -51,6 +51,12 @@ enum
wxCONTROL_DIRTY = 0x80000000 wxCONTROL_DIRTY = 0x80000000
}; };
#ifdef __WXX11__
#define wxUSE_TWO_WINDOWS 1
#else
#define wxUSE_TWO_WINDOWS 0
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxWindow // wxWindow
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -34,6 +34,10 @@ extern void wxDeleteWindowFromTable(Window w);
extern wxWindow *wxGetWindowFromTable(Window w); extern wxWindow *wxGetWindowFromTable(Window w);
extern bool wxAddWindowToTable(Window w, wxWindow *win); extern bool wxAddWindowToTable(Window w, wxWindow *win);
extern void wxDeleteClientWindowFromTable(Window w);
extern wxWindow *wxGetClientWindowFromTable(Window w);
extern bool wxAddClientWindowToTable(Window w, wxWindow *win);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TranslateXXXEvent() functions - translate X event to wxWindow one // TranslateXXXEvent() functions - translate X event to wxWindow one
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -63,8 +63,8 @@ class wxAdoptedWindow: public wxWindow
wxAdoptedWindow(WXWindow window); wxAdoptedWindow(WXWindow window);
~wxAdoptedWindow(); ~wxAdoptedWindow();
void SetHandle(WXWindow window) { m_mainWidget = window; } void SetHandle(WXWindow window) { m_mainWindow = window; }
WXWindow GetHandle() const { return GetXWindow(); } WXWindow GetHandle() const { return GetMainWindow(); }
}; };
#endif #endif

View File

@@ -103,12 +103,11 @@ public:
// accessors // accessors
// --------- // ---------
// Get main widget for this window, e.g. a text widget // Get main X11 window
virtual WXWindow GetMainWindow() const; virtual WXWindow GetMainWindow() const;
// Get the underlying X window and display // Get X11 window representing the client area
WXWindow GetXWindow() const; virtual WXWindow GetClientWindow() const;
WXDisplay *GetXDisplay() const;
void SetLastClick(int button, long timestamp) void SetLastClick(int button, long timestamp)
{ m_lastButton = button; m_lastTS = timestamp; } { m_lastButton = button; m_lastTS = timestamp; }
@@ -123,6 +122,9 @@ public:
// Generates paint events from m_updateRegion // Generates paint events from m_updateRegion
void SendPaintEvents(); void SendPaintEvents();
// Generates paint events from flag
void SendNcPaintEvents();
// Generates erase events from m_clearRegion // Generates erase events from m_clearRegion
void SendEraseEvents(); void SendEraseEvents();
@@ -132,6 +134,14 @@ public:
// Return clear region // Return clear region
wxRegion &GetClearRegion() { return m_clearRegion; } wxRegion &GetClearRegion() { return m_clearRegion; }
void NeedUpdateNcAreaInIdle( bool update = TRUE ) { m_updateNcArea = update; }
// Inserting into main window instead of client
// window. This is mostly for a wxWindow's own
// scrollbars.
void SetInsertIntoMain( bool insert = TRUE ) { m_insertIntoMain = insert; }
bool GetInsertIntoMain() { return m_insertIntoMain; }
// sets the fore/background colour for the given widget // sets the fore/background colour for the given widget
static void DoChangeForegroundColour(WXWindow widget, wxColour& foregroundColour); static void DoChangeForegroundColour(WXWindow widget, wxColour& foregroundColour);
static void DoChangeBackgroundColour(WXWindow widget, wxColour& backgroundColour, bool changeArmColour = FALSE); static void DoChangeBackgroundColour(WXWindow widget, wxColour& backgroundColour, bool changeArmColour = FALSE);
@@ -148,10 +158,6 @@ public:
// For compatibility across platforms (not in event table) // For compatibility across platforms (not in event table)
void OnIdle(wxIdleEvent& WXUNUSED(event)) {} void OnIdle(wxIdleEvent& WXUNUSED(event)) {}
// Go up to a toplevel window and query which window has the focus.
// May return NULL.
wxWindow *GetFocusWidget();
protected: protected:
// Responds to colour changes: passes event on to children. // Responds to colour changes: passes event on to children.
void OnSysColourChanged(wxSysColourChangedEvent& event); void OnSysColourChanged(wxSysColourChangedEvent& event);
@@ -161,10 +167,14 @@ protected:
int m_lastButton; // last pressed button int m_lastButton; // last pressed button
protected: protected:
WXWindow m_mainWidget; WXWindow m_mainWindow;
WXWindow m_clientWindow;
bool m_insertIntoMain;
bool m_winCaptured;
wxRegion m_clearRegion; wxRegion m_clearRegion;
bool m_clipPaintRegion; bool m_clipPaintRegion;
bool m_winCaptured; // ???? bool m_updateNcArea;
bool m_needsInputFocus; // Input focus set in OnIdle bool m_needsInputFocus; // Input focus set in OnIdle
// implement the base class pure virtuals // implement the base class pure virtuals

View File

@@ -132,9 +132,15 @@ bool wxWindow::Create(wxWindow *parent,
// if we should always have the scrollbar, do show it // if we should always have the scrollbar, do show it
if ( GetWindowStyle() & wxALWAYS_SHOW_SB ) if ( GetWindowStyle() & wxALWAYS_SHOW_SB )
{ {
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( TRUE );
#endif
m_scrollbarVert = new wxScrollBar(this, -1, m_scrollbarVert = new wxScrollBar(this, -1,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
wxSB_VERTICAL); wxSB_VERTICAL);
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( FALSE );
#endif
// and position it // and position it
PositionScrollbars(); PositionScrollbars();
@@ -456,7 +462,7 @@ void wxWindow::OnSize(wxSizeEvent& event)
PositionScrollbars(); PositionScrollbars();
} }
#ifndef __WXMSW__ #if 0 // ndef __WXMSW__
// Refresh the area (strip) previously occupied by the border // Refresh the area (strip) previously occupied by the border
if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ) && IsShown()) if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ) && IsShown())
@@ -581,8 +587,11 @@ wxPoint wxWindow::GetClientAreaOrigin() const
{ {
wxPoint pt = wxWindowBase::GetClientAreaOrigin(); wxPoint pt = wxWindowBase::GetClientAreaOrigin();
#if wxUSE_TWO_WINDOWS
#else
if ( m_renderer ) if ( m_renderer )
pt += m_renderer->GetBorderDimensions(GetBorder()).GetPosition(); pt += m_renderer->GetBorderDimensions(GetBorder()).GetPosition();
#endif
return pt; return pt;
} }
@@ -771,10 +780,16 @@ void wxWindow::SetScrollbar(int orient,
if ( !scrollbar ) if ( !scrollbar )
{ {
// create it // create it
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( TRUE );
#endif
scrollbar = new wxScrollBar(this, -1, scrollbar = new wxScrollBar(this, -1,
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
orient & wxVERTICAL ? wxSB_VERTICAL orient & wxVERTICAL ? wxSB_VERTICAL
: wxSB_HORIZONTAL); : wxSB_HORIZONTAL);
#if wxUSE_TWO_WINDOWS
SetInsertIntoMain( FALSE );
#endif
if ( orient & wxVERTICAL ) if ( orient & wxVERTICAL )
m_scrollbarVert = scrollbar; m_scrollbarVert = scrollbar;
else else

View File

@@ -49,6 +49,7 @@
extern wxList wxPendingDelete; extern wxList wxPendingDelete;
wxHashTable *wxWidgetHashTable = NULL; wxHashTable *wxWidgetHashTable = NULL;
wxHashTable *wxClientWidgetHashTable = NULL;
wxApp *wxTheApp = NULL; wxApp *wxTheApp = NULL;
@@ -119,6 +120,7 @@ bool wxApp::Initialize()
#endif #endif
wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER); wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
wxClientWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
wxModule::RegisterModules(); wxModule::RegisterModules();
if (!wxModule::InitializeModules()) return FALSE; if (!wxModule::InitializeModules()) return FALSE;
@@ -134,6 +136,8 @@ void wxApp::CleanUp()
delete wxWidgetHashTable; delete wxWidgetHashTable;
wxWidgetHashTable = NULL; wxWidgetHashTable = NULL;
delete wxClientWidgetHashTable;
wxClientWidgetHashTable = NULL;
wxModule::CleanUpModules(); wxModule::CleanUpModules();
@@ -466,10 +470,16 @@ bool wxApp::ProcessXEvent(WXEvent* _event)
// has been destroyed, assume a 1:1 match between // has been destroyed, assume a 1:1 match between
// Window and wxWindow, so if it's not in the table, // Window and wxWindow, so if it's not in the table,
// it must have been destroyed. // it must have been destroyed.
win = wxGetWindowFromTable(window); win = wxGetWindowFromTable(window);
if (!win) if (!win)
return FALSE; {
#if wxUSE_TWO_WINDOWS
win = wxGetClientWindowFromTable(window);
if (!win)
#endif
return FALSE;
}
#ifdef __WXDEBUG__ #ifdef __WXDEBUG__
wxString windowClass = win->GetClassInfo()->GetClassName(); wxString windowClass = win->GetClassInfo()->GetClassName();
@@ -479,30 +489,49 @@ bool wxApp::ProcessXEvent(WXEvent* _event)
{ {
case Expose: case Expose:
{ {
//wxLogDebug("Expose: %s", windowClass.c_str()); #if wxUSE_TWO_WINDOWS
win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event), if (event->xexpose.window != (Window)win->GetClientWindow())
XExposeEventGetWidth(event), XExposeEventGetHeight(event)); {
XEvent tmp_event;
wxExposeInfo info;
info.window = event->xexpose.window;
info.found_non_matching = FALSE;
while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info ))
{
// Don't worry about optimizing redrawing the border etc.
}
win->NeedUpdateNcAreaInIdle();
}
else
#endif
{
win->GetUpdateRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
XExposeEventGetWidth(event), XExposeEventGetHeight(event));
win->GetClearRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event), win->GetClearRegion().Union( XExposeEventGetX(event), XExposeEventGetY(event),
XExposeEventGetWidth(event), XExposeEventGetHeight(event)); XExposeEventGetWidth(event), XExposeEventGetHeight(event));
#if !wxUSE_NANOX #if !wxUSE_NANOX
XEvent tmp_event; XEvent tmp_event;
wxExposeInfo info; wxExposeInfo info;
info.window = event->xexpose.window; info.window = event->xexpose.window;
info.found_non_matching = FALSE; info.found_non_matching = FALSE;
while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info )) while (XCheckIfEvent( wxGlobalDisplay(), &tmp_event, expose_predicate, (XPointer) &info ))
{ {
win->GetUpdateRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y, win->GetUpdateRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y,
tmp_event.xexpose.width, tmp_event.xexpose.height ); tmp_event.xexpose.width, tmp_event.xexpose.height );
win->GetClearRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y, win->GetClearRegion().Union( tmp_event.xexpose.x, tmp_event.xexpose.y,
tmp_event.xexpose.width, tmp_event.xexpose.height ); tmp_event.xexpose.width, tmp_event.xexpose.height );
} }
#endif #endif
if (win->GetMainWindow() == win->GetClientWindow())
win->NeedUpdateNcAreaInIdle();
// Only erase background, paint in idle time. // Only erase background, paint in idle time.
win->SendEraseEvents(); win->SendEraseEvents();
//win->Update();
}
return TRUE; return TRUE;
} }
@@ -580,7 +609,6 @@ bool wxApp::ProcessXEvent(WXEvent* _event)
if (event->update.utype == GR_UPDATE_SIZE) if (event->update.utype == GR_UPDATE_SIZE)
#endif #endif
{ {
//wxLogDebug("ConfigureNotify: %s", windowClass.c_str());
if (win->IsTopLevel() && win->IsShown()) if (win->IsTopLevel() && win->IsShown())
{ {
wxTopLevelWindowX11 *tlw = (wxTopLevelWindowX11 *) win; wxTopLevelWindowX11 *tlw = (wxTopLevelWindowX11 *) win;

View File

@@ -2030,53 +2030,24 @@ int wxWindowDC::GetDepth() const
return -1; return -1;
} }
// ----------------------------------------------------------------------------
// wxPaintDC
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC)
wxPaintDC::wxPaintDC(wxWindow* win)
: wxClientDC(win)
{
#if USE_PAINT_REGION
if (!win->GetClipPaintRegion())
return;
m_paintClippingRegion = win->GetUpdateRegion();
Region region = (Region) m_paintClippingRegion.GetX11Region();
if (region)
{
m_paintClippingRegion = win->GetUpdateRegion();
Region region2 = (Region) m_paintClippingRegion.GetX11Region();
if (region2)
{
m_currentClippingRegion.Union( m_paintClippingRegion );
XSetRegion( (Display*) m_display, (GC) m_penGC, region2 );
XSetRegion( (Display*) m_display, (GC) m_brushGC, region2 );
XSetRegion( (Display*) m_display, (GC) m_textGC, region2 );
XSetRegion( (Display*) m_display, (GC) m_bgGC, region2 );
}
}
#endif // USE_PAINT_REGION
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxClientDC // wxClientDC
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC) IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
wxClientDC::wxClientDC( wxWindow *win ) wxClientDC::wxClientDC( wxWindow *window )
: wxWindowDC( win ) : wxWindowDC( window )
{ {
wxCHECK_RET( win, _T("NULL window in wxClientDC::wxClientDC") ); wxCHECK_RET( window, _T("NULL window in wxClientDC::wxClientDC") );
#ifdef __WXUNIVERSAL__ m_window = (WXWindow*) window->GetClientWindow();
wxPoint ptOrigin = win->GetClientAreaOrigin();
#if wxUSE_TWO_WINDOWS
#else
wxPoint ptOrigin = window->GetClientAreaOrigin();
SetDeviceOrigin(ptOrigin.x, ptOrigin.y); SetDeviceOrigin(ptOrigin.x, ptOrigin.y);
wxSize size = win->GetClientSize(); wxSize size = window->GetClientSize();
SetClippingRegion(wxPoint(0, 0), size); SetClippingRegion(wxPoint(0, 0), size);
#endif // __WXUNIVERSAL__ #endif // __WXUNIVERSAL__
} }
@@ -2088,6 +2059,33 @@ void wxClientDC::DoGetSize(int *width, int *height) const
m_owner->GetClientSize( width, height ); m_owner->GetClientSize( width, height );
} }
// ----------------------------------------------------------------------------
// wxPaintDC
// ----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC)
wxPaintDC::wxPaintDC(wxWindow* window)
: wxClientDC(window)
{
#if USE_PAINT_REGION
if (!window->GetClipPaintRegion())
return;
m_paintClippingRegion = window->GetUpdateRegion();
Region region = (Region) m_paintClippingRegion.GetX11Region();
if (region)
{
m_currentClippingRegion.Union( m_paintClippingRegion );
XSetRegion( (Display*) m_display, (GC) m_penGC, region );
XSetRegion( (Display*) m_display, (GC) m_brushGC, region );
XSetRegion( (Display*) m_display, (GC) m_textGC, region );
XSetRegion( (Display*) m_display, (GC) m_bgGC, region );
}
#endif // USE_PAINT_REGION
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxDCModule // wxDCModule
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -78,7 +78,8 @@ bool wxPopupWindow::Create( wxWindow *parent, int style )
KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
PropertyChangeMask ); PropertyChangeMask );
m_mainWidget = (WXWindow) xwindow; m_mainWindow = (WXWindow) xwindow;
m_clientWindow = (WXWindow) xwindow;
wxAddWindowToTable( xwindow, (wxWindow*) this ); wxAddWindowToTable( xwindow, (wxWindow*) this );
// Set background to None which will prevent X11 from clearing the // Set background to None which will prevent X11 from clearing the

View File

@@ -94,7 +94,7 @@ wxAdoptedWindow::wxAdoptedWindow()
wxAdoptedWindow::wxAdoptedWindow(WXWindow window) wxAdoptedWindow::wxAdoptedWindow(WXWindow window)
{ {
m_mainWidget = window; m_mainWindow = window;
} }
wxAdoptedWindow::~wxAdoptedWindow() wxAdoptedWindow::~wxAdoptedWindow()
@@ -131,15 +131,15 @@ bool wxReparenter::Reparent(wxWindow* newParent, wxAdoptedWindow* toReparent)
int parentOffset = 0; int parentOffset = 0;
old = XSetErrorHandler(ErrorHandler); old = XSetErrorHandler(ErrorHandler);
XReparentWindow((Display*) newParent->GetXDisplay(), XReparentWindow( wxGlobalDisplay(),
(Window) toReparent->GetXWindow(), (Window) toReparent->GetMainWindow(),
(Window) newParent->GetXWindow(), (Window) newParent->GetMainWindow(),
0, 0); 0, 0);
if (!XQueryTree((Display*) newParent->GetXDisplay(), if (!XQueryTree( wxGlobalDisplay(),
(Window) toReparent->GetXWindow(), (Window) toReparent->GetMainWindow(),
&returnroot, &returnparent, &returnroot, &returnparent,
&children, &numchildren) || Xerror) &children, &numchildren) || Xerror)
{ {
XSetErrorHandler(old); XSetErrorHandler(old);
return TRUE; return TRUE;
@@ -160,14 +160,14 @@ bool wxReparenter::Reparent(wxWindow* newParent, wxAdoptedWindow* toReparent)
*/ */
for (each=0; each<numchildren; each++) for (each=0; each<numchildren; each++)
{ {
XGetWindowAttributes((Display*) newParent->GetXDisplay(), XGetWindowAttributes( wxGlobalDisplay(),
children[each], &xwa); children[each], &xwa);
fprintf(stderr, fprintf(stderr,
"Reparenting child at offset %d and position %d, %d.\n", "Reparenting child at offset %d and position %d, %d.\n",
parentOffset, parentOffset+xwa.x, parentOffset+xwa.y); parentOffset, parentOffset+xwa.x, parentOffset+xwa.y);
XReparentWindow((Display*) newParent->GetXDisplay(), XReparentWindow( wxGlobalDisplay(),
children[each], (Window) newParent->GetXWindow(), children[each], (Window) newParent->GetMainWindow(),
xwa.x, xwa.y); xwa.x, xwa.y);
} }
} }
@@ -187,7 +187,7 @@ bool wxReparenter::WaitAndReparent(wxWindow* newParent, wxAdoptedWindow* toRepar
sm_exactMatch = exactMatch; sm_exactMatch = exactMatch;
sm_name = windowName; sm_name = windowName;
Display* display = (Display*) newParent->GetXDisplay() ; Display* display = wxGlobalDisplay();
XSelectInput(display, XSelectInput(display,
RootWindowOfScreen(DefaultScreenOfDisplay(display)), RootWindowOfScreen(DefaultScreenOfDisplay(display)),
SubstructureNotifyMask); SubstructureNotifyMask);

View File

@@ -123,12 +123,18 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
xattributes.background_pixel = m_backgroundColour.GetPixel(); xattributes.background_pixel = m_backgroundColour.GetPixel();
xattributes.border_pixel = BlackPixel( xdisplay, xscreen ); xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
if (HasFlag( wxNO_BORDER ))
{
xattributes_mask |= CWOverrideRedirect;
xattributes.override_redirect = True;
}
if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE )) if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ))
{ {
xattributes_mask |= CWBitGravity; xattributes_mask |= CWBitGravity;
xattributes.bit_gravity = StaticGravity; xattributes.bit_gravity = StaticGravity;
} }
xattributes_mask |= CWEventMask; xattributes_mask |= CWEventMask;
xattributes.event_mask = xattributes.event_mask =
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
@@ -147,7 +153,9 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
0, 0, InputOutput, xvisual, backColor, foreColor); 0, 0, InputOutput, xvisual, backColor, foreColor);
#endif #endif
m_mainWidget = (WXWindow) xwindow; m_mainWindow = (WXWindow) xwindow;
m_clientWindow = (WXWindow) xwindow;
wxAddWindowToTable( xwindow, (wxWindow*) this );
#if wxUSE_NANOX #if wxUSE_NANOX
XSelectInput( xdisplay, xwindow, XSelectInput( xdisplay, xwindow,
@@ -168,20 +176,26 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
PropertyChangeMask PropertyChangeMask
); );
#endif #endif
wxAddWindowToTable( xwindow, (wxWindow*) this );
// Set background to None which will prevent X11 from clearing the // Set background to None which will prevent X11 from clearing the
// background completely. // background completely.
XSetWindowBackgroundPixmap( xdisplay, xwindow, None ); XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
#if !wxUSE_NANOX #if !wxUSE_NANOX
if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) if (HasFlag( wxSTAY_ON_TOP ))
{ {
if (GetParent() && GetParent()->GetMainWindow()) Window xroot = RootWindow( xdisplay, xscreen );
{ XSetTransientForHint( xdisplay, xwindow, xroot );
Window xparentwindow = (Window) GetParent()->GetMainWindow(); }
XSetTransientForHint( xdisplay, xwindow, xparentwindow ); else
{
if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
{
if (GetParent() && GetParent()->GetMainWindow())
{
Window xparentwindow = (Window) GetParent()->GetMainWindow();
XSetTransientForHint( xdisplay, xwindow, xparentwindow );
}
} }
} }
@@ -193,7 +207,12 @@ bool wxTopLevelWindowX11::Create(wxWindow *parent,
XSetWMNormalHints( xdisplay, xwindow, &size_hints); XSetWMNormalHints( xdisplay, xwindow, &size_hints);
XWMHints wm_hints; XWMHints wm_hints;
wm_hints.flags = InputHint | StateHint /* | WindowGroupHint */; wm_hints.flags = InputHint | StateHint;
if (GetParent())
{
wm_hints.flags |= WindowGroupHint;
wm_hints.window_group = (Window) GetParent()->GetMainWindow();
}
wm_hints.input = True; wm_hints.input = True;
wm_hints.initial_state = NormalState; wm_hints.initial_state = NormalState;
XSetWMHints( xdisplay, xwindow, &wm_hints); XSetWMHints( xdisplay, xwindow, &wm_hints);
@@ -266,6 +285,8 @@ void wxTopLevelWindowX11::OnInternalIdle()
bool wxTopLevelWindowX11::Show(bool show) bool wxTopLevelWindowX11::Show(bool show)
{ {
XSync( wxGlobalDisplay(), False );
// Nano-X has to force a size event, // Nano-X has to force a size event,
// else there's no initial size. // else there's no initial size.
#if wxUSE_NANOX #if wxUSE_NANOX
@@ -619,7 +640,7 @@ void wxTopLevelWindowX11::DoSetClientSize(int width, int height)
size_hints.flags = PSize; size_hints.flags = PSize;
size_hints.width = width + (oldSize.x - oldClientSize.x); size_hints.width = width + (oldSize.x - oldClientSize.x);
size_hints.height = height + (oldSize.y - oldClientSize.y); size_hints.height = height + (oldSize.y - oldClientSize.y);
XSetWMNormalHints( (Display*) GetXDisplay(), (Window) GetMainWindow(), XSetWMNormalHints( wxGlobalDisplay(), (Window) GetMainWindow(),
&size_hints); &size_hints);
// This seems to be necessary or resizes don't get performed // This seems to be necessary or resizes don't get performed
@@ -644,11 +665,11 @@ void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int siz
wxWindowX11::DoSetSize(x, y, width, height, sizeFlags); wxWindowX11::DoSetSize(x, y, width, height, sizeFlags);
#endif #endif
XSync(wxGlobalDisplay(), False); XSync(wxGlobalDisplay(), False);
Window window = (Window) m_mainWidget; Window window = (Window) m_mainWindow;
if (!window) if (!window)
return ; return ;
Display *display = (Display*) GetXDisplay(); Display *display = wxGlobalDisplay();
Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display)); Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
Window parent_window = window, Window parent_window = window,
next_parent = window; next_parent = window;
@@ -708,7 +729,7 @@ void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int siz
size_hints.height = height; size_hints.height = height;
size_hints.x = x; size_hints.x = x;
size_hints.y = y; size_hints.y = y;
XSetWMNormalHints( (Display*) GetXDisplay(), (Window) GetMainWindow(), XSetWMNormalHints( wxGlobalDisplay(), (Window) GetMainWindow(),
&size_hints); &size_hints);
// This seems to be necessary or resizes don't get performed. // This seems to be necessary or resizes don't get performed.
@@ -727,11 +748,11 @@ void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int siz
void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const
{ {
XSync(wxGlobalDisplay(), False); XSync(wxGlobalDisplay(), False);
Window window = (Window) m_mainWidget; Window window = (Window) m_mainWindow;
if (!window) if (!window)
return ; return ;
Display *display = (Display*) GetXDisplay(); Display *display = wxGlobalDisplay();
Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display)); Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
Window parent_window = window, Window parent_window = window,
next_parent = window; next_parent = window;
@@ -758,7 +779,7 @@ void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const
if (y) *y = yy; if (y) *y = yy;
#else #else
XWindowAttributes attr; XWindowAttributes attr;
Status status = XGetWindowAttributes((Display*) GetXDisplay(), parent_window, & attr); Status status = XGetWindowAttributes( wxGlobalDisplay(), parent_window, & attr);
if (status) if (status)
{ {
if (x) *x = attr.x; if (x) *x = attr.x;

View File

@@ -36,6 +36,7 @@
#include "wx/msgdlg.h" #include "wx/msgdlg.h"
#include "wx/frame.h" #include "wx/frame.h"
#include "wx/scrolwin.h" #include "wx/scrolwin.h"
#include "wx/scrolbar.h"
#include "wx/module.h" #include "wx/module.h"
#include "wx/menuitem.h" #include "wx/menuitem.h"
#include "wx/log.h" #include "wx/log.h"
@@ -59,6 +60,7 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
extern wxHashTable *wxWidgetHashTable; extern wxHashTable *wxWidgetHashTable;
extern wxHashTable *wxClientWidgetHashTable;
static wxWindow* g_captureWindow = NULL; static wxWindow* g_captureWindow = NULL;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -97,7 +99,10 @@ void wxWindowX11::Init()
InitBase(); InitBase();
// X11-specific // X11-specific
m_mainWidget = (WXWindow) 0; m_mainWindow = (WXWindow) 0;
m_clientWindow = (WXWindow) 0;
m_insertIntoMain = FALSE;
m_winCaptured = FALSE; m_winCaptured = FALSE;
m_needsInputFocus = FALSE; m_needsInputFocus = FALSE;
m_isShown = TRUE; m_isShown = TRUE;
@@ -139,7 +144,14 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
m_foregroundColour = *wxBLACK; m_foregroundColour = *wxBLACK;
m_foregroundColour.CalcPixel( (WXColormap) cm ); m_foregroundColour.CalcPixel( (WXColormap) cm );
Window xparent = (Window) parent->GetMainWindow(); Window xparent = (Window) parent->GetClientWindow();
// Add window's own scrollbars to main window, not to client window
if (parent->GetInsertIntoMain())
{
// wxLogDebug( "Inserted into main: %s", GetName().c_str() );
xparent = (Window) parent->GetMainWindow();
}
wxSize size2(size); wxSize size2(size);
if (size2.x == -1) if (size2.x == -1)
@@ -154,29 +166,89 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
pos2.y = 0; pos2.y = 0;
#if !wxUSE_NANOX #if !wxUSE_NANOX
#if wxUSE_TWO_WINDOWS
bool need_two_windows =
((( wxSUNKEN_BORDER | wxRAISED_BORDER | wxSIMPLE_BORDER | wxHSCROLL | wxVSCROLL ) & m_windowStyle) != 0);
#else
bool need_two_windows = FALSE;
#endif
XSetWindowAttributes xattributes; XSetWindowAttributes xattributes;
long xattributes_mask = 0;
long xattributes_mask = xattributes_mask |= CWBackPixel;
CWBorderPixel | CWBackPixel;
xattributes.background_pixel = m_backgroundColour.GetPixel(); xattributes.background_pixel = m_backgroundColour.GetPixel();
xattributes_mask |= CWBorderPixel;
xattributes.border_pixel = BlackPixel( xdisplay, xscreen ); xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
xattributes_mask |= CWEventMask; xattributes_mask |= CWEventMask;
xattributes.event_mask =
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | if (need_two_windows)
ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
PropertyChangeMask | VisibilityChangeMask ;
if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ))
{ {
xattributes_mask |= CWBitGravity; xattributes.event_mask =
xattributes.bit_gravity = StaticGravity; ExposureMask | StructureNotifyMask | ColormapChangeMask;
}
Window xwindow = XCreateWindow( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y, Window xwindow = XCreateWindow( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y,
0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes ); 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
m_mainWindow = (WXWindow) xwindow;
wxAddWindowToTable( xwindow, (wxWindow*) this );
XMapWindow( xdisplay, xwindow );
xattributes.event_mask =
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
PropertyChangeMask | VisibilityChangeMask ;
if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ))
{
xattributes_mask |= CWBitGravity;
xattributes.bit_gravity = StaticGravity;
}
xwindow = XCreateWindow( xdisplay, xwindow, 0, 0, size2.x, size2.y,
0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
m_clientWindow = (WXWindow) xwindow;
wxAddClientWindowToTable( xwindow, (wxWindow*) this );
XMapWindow( xdisplay, xwindow );
}
else
{
// wxLogDebug( "No two windows needed %s", GetName().c_str() );
xattributes.event_mask =
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
PropertyChangeMask | VisibilityChangeMask ;
if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ))
{
xattributes_mask |= CWBitGravity;
xattributes.bit_gravity = StaticGravity;
}
Window xwindow = XCreateWindow( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y,
0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
m_mainWindow = (WXWindow) xwindow;
m_clientWindow = m_mainWindow;
wxAddWindowToTable( xwindow, (wxWindow*) this );
XMapWindow( xdisplay, xwindow );
}
#else #else
int extraFlags = GR_EVENT_MASK_CLOSE_REQ; int extraFlags = GR_EVENT_MASK_CLOSE_REQ;
@@ -192,24 +264,22 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
PropertyChangeMask ); PropertyChangeMask );
#endif
m_mainWidget = (WXWindow) xwindow; XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
m_mainWindow = (WXWindow) xwindow;
wxAddWindowToTable( xwindow, (wxWindow*) this ); wxAddWindowToTable( xwindow, (wxWindow*) this );
XMapWindow( xdisplay, xwindow );
#endif
// Is a subwindow, so map immediately // Is a subwindow, so map immediately
m_isShown = TRUE; m_isShown = TRUE;
XMapWindow( xdisplay, xwindow );
// Without this, the cursor may not be restored properly (e.g. in splitter // Without this, the cursor may not be restored properly (e.g. in splitter
// sample). // sample).
SetCursor(*wxSTANDARD_CURSOR); SetCursor(*wxSTANDARD_CURSOR);
SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
// Set background to None which will prevent X11 from clearing the
// background comletely.
XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
// Don't call this, it can have nasty repercussions for composite controls, // Don't call this, it can have nasty repercussions for composite controls,
// for example // for example
@@ -226,22 +296,25 @@ wxWindowX11::~wxWindowX11()
m_isBeingDeleted = TRUE; m_isBeingDeleted = TRUE;
// X11-specific actions first
Window xwindow = (Window) m_mainWidget;
if (m_parent) if (m_parent)
m_parent->RemoveChild( this ); m_parent->RemoveChild( this );
DestroyChildren(); DestroyChildren();
// Destroy the window if (m_clientWindow != m_mainWindow)
if (xwindow)
{ {
XSelectInput( wxGlobalDisplay(), xwindow, NoEventMask); // Destroy the cleint window
wxDeleteWindowFromTable( xwindow ); Window xwindow = (Window) m_clientWindow;
wxDeleteClientWindowFromTable( xwindow );
XDestroyWindow( wxGlobalDisplay(), xwindow ); XDestroyWindow( wxGlobalDisplay(), xwindow );
m_mainWidget = NULL; m_clientWindow = NULL;
} }
// Destroy the window
Window xwindow = (Window) m_mainWindow;
wxDeleteWindowFromTable( xwindow );
XDestroyWindow( wxGlobalDisplay(), xwindow );
m_mainWindow = NULL;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -250,7 +323,7 @@ wxWindowX11::~wxWindowX11()
void wxWindowX11::SetFocus() void wxWindowX11::SetFocus()
{ {
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_clientWindow;
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
@@ -292,19 +365,6 @@ wxWindow *wxWindowBase::FindFocus()
return NULL; return NULL;
} }
wxWindow *wxWindowX11::GetFocusWidget()
{
wxWindow *win = (wxWindow*) this;
while (!win->IsTopLevel())
{
win = win->GetParent();
if (!win)
return (wxWindow*) NULL;
}
return win;
}
// Enabling/disabling handled by event loop, and not sending events // Enabling/disabling handled by event loop, and not sending events
// if disabled. // if disabled.
bool wxWindowX11::Enable(bool enable) bool wxWindowX11::Enable(bool enable)
@@ -319,18 +379,17 @@ bool wxWindowX11::Show(bool show)
{ {
wxWindowBase::Show(show); wxWindowBase::Show(show);
Window xwin = (Window) GetXWindow(); Window xwindow = (Window) m_mainWindow;
Display *xdisp = (Display*) GetXDisplay(); Display *xdisp = wxGlobalDisplay();
if (show) if (show)
{ {
// wxLogDebug( "Mapping window of type %s", GetName().c_str() ); // wxLogDebug( "Mapping window of type %s", GetName().c_str() );
XMapWindow(xdisp, xwin); XMapWindow(xdisp, xwindow);
XSync(xdisp, False);
} }
else else
{ {
// wxLogDebug( "Unmapping window of type %s", GetName().c_str() ); // wxLogDebug( "Unmapping window of type %s", GetName().c_str() );
XUnmapWindow(xdisp, xwin); XUnmapWindow(xdisp, xwindow);
} }
return TRUE; return TRUE;
@@ -339,15 +398,15 @@ bool wxWindowX11::Show(bool show)
// Raise the window to the top of the Z order // Raise the window to the top of the Z order
void wxWindowX11::Raise() void wxWindowX11::Raise()
{ {
if (m_mainWidget) if (m_mainWindow)
XRaiseWindow( wxGlobalDisplay(), (Window) m_mainWidget ); XRaiseWindow( wxGlobalDisplay(), (Window) m_mainWindow );
} }
// Lower the window to the bottom of the Z order // Lower the window to the bottom of the Z order
void wxWindowX11::Lower() void wxWindowX11::Lower()
{ {
if (m_mainWidget) if (m_mainWindow)
XLowerWindow( wxGlobalDisplay(), (Window) m_mainWidget ); XLowerWindow( wxGlobalDisplay(), (Window) m_mainWindow );
} }
void wxWindowX11::DoCaptureMouse() void wxWindowX11::DoCaptureMouse()
@@ -365,7 +424,7 @@ void wxWindowX11::DoCaptureMouse()
if (m_winCaptured) if (m_winCaptured)
return; return;
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_clientWindow;
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
@@ -395,44 +454,6 @@ void wxWindowX11::DoCaptureMouse()
return; return;
} }
// wxLogDebug("Grabbed pointer in %s", GetName().c_str() );
#if 0
res = XGrabButton(wxGlobalDisplay(), AnyButton, AnyModifier,
(Window) GetMainWindow(),
FALSE,
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
GrabModeAsync,
GrabModeAsync,
None,
None);
if (res != GrabSuccess)
{
wxLogDebug("Failed to grab mouse buttons.");
XUngrabPointer(wxGlobalDisplay(), CurrentTime);
return;
}
#endif
#if 0
res = XGrabKeyboard(wxGlobalDisplay(), (Window) GetMainWindow(),
ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask,
FALSE,
GrabModeAsync,
GrabModeAsync,
CurrentTime);
if (res != GrabSuccess)
{
wxLogDebug("Failed to grab keyboard.");
XUngrabPointer(wxGlobalDisplay(), CurrentTime);
XUngrabButton(wxGlobalDisplay(), AnyButton, AnyModifier,
(Window) GetMainWindow());
return;
}
#endif
m_winCaptured = TRUE; m_winCaptured = TRUE;
} }
} }
@@ -444,15 +465,11 @@ void wxWindowX11::DoReleaseMouse()
if ( !m_winCaptured ) if ( !m_winCaptured )
return; return;
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_clientWindow;
if (xwindow) if (xwindow)
{ {
XUngrabPointer( wxGlobalDisplay(), CurrentTime ); XUngrabPointer( wxGlobalDisplay(), CurrentTime );
#if 0
XUngrabButton( wxGlobalDisplay(), AnyButton, AnyModifier, xwindow);
XUngrabKeyboard( wxGlobalDisplay(), CurrentTime );
#endif
} }
// wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() ); // wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() );
@@ -479,7 +496,7 @@ bool wxWindowX11::SetCursor(const wxCursor& cursor)
return FALSE; return FALSE;
} }
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_clientWindow;
wxCHECK_MSG( xwindow, FALSE, wxT("invalid window") ); wxCHECK_MSG( xwindow, FALSE, wxT("invalid window") );
@@ -499,7 +516,7 @@ bool wxWindowX11::SetCursor(const wxCursor& cursor)
// Coordinates relative to the window // Coordinates relative to the window
void wxWindowX11::WarpPointer (int x, int y) void wxWindowX11::WarpPointer (int x, int y)
{ {
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_clientWindow;
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
@@ -532,7 +549,7 @@ void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
m_clearRegion.Intersect( 0, 0, cw, ch ); m_clearRegion.Intersect( 0, 0, cw, ch );
} }
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) GetClientWindow();
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
@@ -560,9 +577,13 @@ void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
GetClientSize( &cw, &ch ); GetClientSize( &cw, &ch );
} }
#if wxUSE_TWO_WINDOWS
wxPoint offset( 0,0 );
#else
wxPoint offset = GetClientAreaOrigin(); wxPoint offset = GetClientAreaOrigin();
s_x += offset.x; s_x += offset.x;
s_y += offset.y; s_y += offset.y;
#endif
int w = cw - abs(dx); int w = cw - abs(dx);
int h = ch - abs(dy); int h = ch - abs(dy);
@@ -644,7 +665,7 @@ bool wxWindowX11::PreResize()
// Get total size // Get total size
void wxWindowX11::DoGetSize(int *x, int *y) const void wxWindowX11::DoGetSize(int *x, int *y) const
{ {
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_mainWindow;
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
@@ -663,7 +684,7 @@ void wxWindowX11::DoGetSize(int *x, int *y) const
void wxWindowX11::DoGetPosition(int *x, int *y) const void wxWindowX11::DoGetPosition(int *x, int *y) const
{ {
Window window = (Window) m_mainWidget; Window window = (Window) m_mainWindow;
if (window) if (window)
{ {
//XSync(wxGlobalDisplay(), False); //XSync(wxGlobalDisplay(), False);
@@ -692,7 +713,7 @@ void wxWindowX11::DoScreenToClient(int *x, int *y) const
{ {
Display *display = wxGlobalDisplay(); Display *display = wxGlobalDisplay();
Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display)); Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
Window thisWindow = (Window) m_mainWidget; Window thisWindow = (Window) m_clientWindow;
Window childWindow; Window childWindow;
int xx = *x; int xx = *x;
@@ -704,7 +725,7 @@ void wxWindowX11::DoClientToScreen(int *x, int *y) const
{ {
Display *display = wxGlobalDisplay(); Display *display = wxGlobalDisplay();
Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display)); Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
Window thisWindow = (Window) m_mainWidget; Window thisWindow = (Window) m_clientWindow;
Window childWindow; Window childWindow;
int xx = *x; int xx = *x;
@@ -716,11 +737,10 @@ void wxWindowX11::DoClientToScreen(int *x, int *y) const
// Get size *available for subwindows* i.e. excluding menu bar etc. // Get size *available for subwindows* i.e. excluding menu bar etc.
void wxWindowX11::DoGetClientSize(int *x, int *y) const void wxWindowX11::DoGetClientSize(int *x, int *y) const
{ {
Window window = (Window) m_mainWidget; Window window = (Window) m_mainWindow;
if (window) if (window)
{ {
//XSync(wxGlobalDisplay(), False); // Is this really a good idea?
XWindowAttributes attr; XWindowAttributes attr;
Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr ); Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr );
wxASSERT(status); wxASSERT(status);
@@ -736,8 +756,8 @@ void wxWindowX11::DoGetClientSize(int *x, int *y) const
void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags) void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{ {
// wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height); // wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height);
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_mainWindow;
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
@@ -749,8 +769,7 @@ void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
int new_y = attr.y; int new_y = attr.y;
int new_w = attr.width; int new_w = attr.width;
int new_h = attr.height; int new_h = attr.height;
if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
{ {
int yy = 0; int yy = 0;
@@ -788,41 +807,30 @@ void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
void wxWindowX11::DoSetClientSize(int width, int height) void wxWindowX11::DoSetClientSize(int width, int height)
{ {
// wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height); // wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height);
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_mainWindow;
wxCHECK_RET( xwindow, wxT("invalid window") ); wxCHECK_RET( xwindow, wxT("invalid window") );
#if 1
XResizeWindow( wxGlobalDisplay(), xwindow, width, height ); XResizeWindow( wxGlobalDisplay(), xwindow, width, height );
#if 0
wxSizeEvent event(wxSize(width, height), GetId());
event.SetEventObject(this);
GetEventHandler()->ProcessEvent(event);
#endif
#else if (m_mainWindow != m_clientWindow)
{
XWindowAttributes attr; xwindow = (Window) m_clientWindow;
Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr );
wxCHECK_RET( status, wxT("invalid window attributes") );
int new_x = attr.x; if (HasFlag( wxSUNKEN_BORDER) || HasFlag( wxRAISED_BORDER))
int new_y = attr.y; {
int new_w = attr.width; width -= 4;
int new_h = attr.height; height -= 4;
} else
if (width != -1) if (HasFlag( wxSIMPLE_BORDER ))
new_w = width; {
width -= 2;
height -= 2;
}
if (height != -1) XResizeWindow( wxGlobalDisplay(), xwindow, width, height );
new_h = height; }
DoMoveWindow( new_x, new_y, new_w, new_h );
#endif
} }
// For implementation purposes - sometimes decorations make the client area // For implementation purposes - sometimes decorations make the client area
@@ -832,6 +840,70 @@ wxPoint wxWindowX11::GetClientAreaOrigin() const
return wxPoint(0, 0); return wxPoint(0, 0);
} }
void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
{
Window xwindow = (Window) m_mainWindow;
wxCHECK_RET( xwindow, wxT("invalid window") );
#if !wxUSE_NANOX
XMoveResizeWindow( wxGlobalDisplay(), xwindow, x, y, width, height );
if (m_mainWindow != m_clientWindow)
{
xwindow = (Window) m_clientWindow;
if (HasFlag( wxSUNKEN_BORDER) || HasFlag( wxRAISED_BORDER))
{
x = 2;
y = 2;
width -= 4;
height -= 4;
} else
if (HasFlag( wxSIMPLE_BORDER ))
{
x = 1;
y = 1;
width -= 2;
height -= 2;
} else
{
x = 0;
y = 0;
}
wxWindow *window = (wxWindow*) this;
wxScrollBar *sb = window->GetScrollbar( wxHORIZONTAL );
if (sb && sb->IsShown())
{
wxSize size = sb->GetSize();
height -= size.y;
}
sb = window->GetScrollbar( wxVERTICAL );
if (sb && sb->IsShown())
{
wxSize size = sb->GetSize();
width -= size.x;
}
XMoveResizeWindow( wxGlobalDisplay(), xwindow, x, y, width, height );
}
#else
XWindowChanges windowChanges;
windowChanges.x = x;
windowChanges.y = y;
windowChanges.width = width;
windowChanges.height = height;
windowChanges.stack_mode = 0;
int valueMask = CWX | CWY | CWWidth | CWHeight;
XConfigureWindow( wxGlobalDisplay(), xwindow, valueMask, &windowChanges );
#endif
}
void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH) void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
{ {
m_minWidth = minW; m_minWidth = minW;
@@ -862,48 +934,7 @@ void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW,
sizeHints.height_inc = incH; sizeHints.height_inc = incH;
} }
XSetWMNormalHints(wxGlobalDisplay(), (Window) GetMainWindow(), & sizeHints); XSetWMNormalHints(wxGlobalDisplay(), (Window) m_mainWindow, &sizeHints );
#endif
}
void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
{
Window xwindow = (Window) GetMainWindow();
wxCHECK_RET( xwindow, wxT("invalid window") );
#if !wxUSE_NANOX
XWindowAttributes attr;
Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr );
wxCHECK_RET( status, wxT("invalid window attributes") );
if (attr.width == width && attr.height == height)
{
XMoveWindow( wxGlobalDisplay(), xwindow, x, y );
return;
}
if (attr.x == x && attr.y == y)
{
XResizeWindow( wxGlobalDisplay(), xwindow, width, height );
return;
}
XMoveResizeWindow( wxGlobalDisplay(), xwindow, x, y, width, height );
#else
XWindowChanges windowChanges;
windowChanges.x = x;
windowChanges.y = y;
windowChanges.width = width;
windowChanges.height = height;
windowChanges.stack_mode = 0;
int valueMask = CWX | CWY | CWWidth | CWHeight;
XConfigureWindow( wxGlobalDisplay(), xwindow, valueMask, &windowChanges );
#endif #endif
} }
@@ -915,7 +946,7 @@ int wxWindowX11::GetCharHeight() const
{ {
wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" ); wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay()); WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
int direction, ascent, descent; int direction, ascent, descent;
XCharStruct overall; XCharStruct overall;
@@ -930,7 +961,7 @@ int wxWindowX11::GetCharWidth() const
{ {
wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" ); wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay()); WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
int direction, ascent, descent; int direction, ascent, descent;
XCharStruct overall; XCharStruct overall;
@@ -950,7 +981,7 @@ void wxWindowX11::GetTextExtent(const wxString& string,
wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") ); wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
WXFontStructPtr pFontStruct = fontToUse.GetFontStruct(1.0, GetXDisplay()); WXFontStructPtr pFontStruct = fontToUse.GetFontStruct(1.0, wxGlobalDisplay());
int direction, ascent, descent2; int direction, ascent, descent2;
XCharStruct overall; XCharStruct overall;
@@ -1018,9 +1049,15 @@ void wxWindowX11::Refresh(bool eraseBack, const wxRect *rect)
void wxWindowX11::Update() void wxWindowX11::Update()
{ {
if (m_updateNcArea)
{
// Send nc paint events.
SendNcPaintEvents();
}
if (!m_updateRegion.IsEmpty()) if (!m_updateRegion.IsEmpty())
{ {
// wxLogDebug("wxWindowX11::Update: %s", GetClassInfo()->GetClassName()); // wxLogDebug("wxWindowX11::Update: %s", GetClassInfo()->GetClassName());
// Actually send erase events. // Actually send erase events.
SendEraseEvents(); SendEraseEvents();
@@ -1031,17 +1068,17 @@ void wxWindowX11::Update()
void wxWindowX11::Clear() void wxWindowX11::Clear()
{ {
wxClientDC dc((wxWindow*) this); // wxClientDC dc((wxWindow*) this);
wxBrush brush(GetBackgroundColour(), wxSOLID); // wxBrush brush(GetBackgroundColour(), wxSOLID);
dc.SetBackground(brush); // dc.SetBackground(brush);
dc.Clear(); // dc.Clear();
} }
void wxWindowX11::SendEraseEvents() void wxWindowX11::SendEraseEvents()
{ {
if (m_clearRegion.IsEmpty()) return; if (m_clearRegion.IsEmpty()) return;
wxWindowDC dc( (wxWindow*)this ); wxClientDC dc( (wxWindow*)this );
dc.SetClippingRegion( m_clearRegion ); dc.SetClippingRegion( m_clearRegion );
wxEraseEvent erase_event( GetId(), &dc ); wxEraseEvent erase_event( GetId(), &dc );
@@ -1049,7 +1086,7 @@ void wxWindowX11::SendEraseEvents()
if (!GetEventHandler()->ProcessEvent(erase_event)) if (!GetEventHandler()->ProcessEvent(erase_event))
{ {
Window xwindow = (Window) GetMainWindow(); Window xwindow = (Window) m_clientWindow;
Display *xdisplay = wxGlobalDisplay(); Display *xdisplay = wxGlobalDisplay();
GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL ); GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL );
XSetFillStyle( xdisplay, xgc, FillSolid ); XSetFillStyle( xdisplay, xgc, FillSolid );
@@ -1073,10 +1110,6 @@ void wxWindowX11::SendPaintEvents()
m_clipPaintRegion = TRUE; m_clipPaintRegion = TRUE;
wxNcPaintEvent nc_paint_event( GetId() );
nc_paint_event.SetEventObject( this );
GetEventHandler()->ProcessEvent( nc_paint_event );
wxPaintEvent paint_event( GetId() ); wxPaintEvent paint_event( GetId() );
paint_event.SetEventObject( this ); paint_event.SetEventObject( this );
GetEventHandler()->ProcessEvent( paint_event ); GetEventHandler()->ProcessEvent( paint_event );
@@ -1086,6 +1119,13 @@ void wxWindowX11::SendPaintEvents()
m_clipPaintRegion = FALSE; m_clipPaintRegion = FALSE;
} }
void wxWindowX11::SendNcPaintEvents()
{
wxNcPaintEvent nc_paint_event( GetId() );
nc_paint_event.SetEventObject( this );
GetEventHandler()->ProcessEvent( nc_paint_event );
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// event handlers // event handlers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1157,6 +1197,38 @@ void wxDeleteWindowFromTable(Window w)
wxWidgetHashTable->Delete((long)w); wxWidgetHashTable->Delete((long)w);
} }
// ----------------------------------------------------------------------------
// function which maintain the global hash table mapping client widgets
// ----------------------------------------------------------------------------
bool wxAddClientWindowToTable(Window w, wxWindow *win)
{
wxWindow *oldItem = NULL;
if ((oldItem = (wxWindow *)wxClientWidgetHashTable->Get ((long) w)))
{
wxLogDebug("Client window table clash: new window is %ld, %s",
(long)w, win->GetClassInfo()->GetClassName());
return FALSE;
}
wxClientWidgetHashTable->Put((long) w, win);
wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
w, win, win->GetClassInfo()->GetClassName());
return TRUE;
}
wxWindow *wxGetClientWindowFromTable(Window w)
{
return (wxWindow *)wxClientWidgetHashTable->Get((long) w);
}
void wxDeleteClientWindowFromTable(Window w)
{
wxClientWidgetHashTable->Delete((long)w);
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// add/remove window from the table // add/remove window from the table
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1165,21 +1237,14 @@ void wxDeleteWindowFromTable(Window w)
// X11-specific accessors // X11-specific accessors
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Get the underlying X window
WXWindow wxWindowX11::GetXWindow() const
{
return GetMainWindow();
}
// Get the underlying X display
WXDisplay *wxWindowX11::GetXDisplay() const
{
return wxGetDisplay();
}
WXWindow wxWindowX11::GetMainWindow() const WXWindow wxWindowX11::GetMainWindow() const
{ {
return m_mainWidget; return m_mainWindow;
}
WXWindow wxWindowX11::GetClientWindow() const
{
return m_clientWindow;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------