X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/83afe21166ad23a402185eef5dd47782597e8f91..c156411a0886a4b49a0c30c36153fb3c1edd4b51:/src/gtk/toplevel.cpp?ds=sidebyside diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index f2005c8c5d..b4a0ed8489 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -15,21 +15,27 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "toplevel.h" #endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + #ifdef __VMS #define XIconifyWindow XICONIFYWINDOW #endif #include "wx/defs.h" +#include "wx/log.h" #include "wx/dialog.h" #include "wx/control.h" #include "wx/app.h" #include "wx/dcclient.h" #include "wx/gtk/private.h" +#include "wx/timer.h" +#include "wx/settings.h" #include #include @@ -225,7 +231,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_ev (char *)"base", 0, 0, -1, -1); - return TRUE; + return FALSE; } //----------------------------------------------------------------------------- @@ -321,14 +327,8 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, // always create a frame of some reasonable, even if arbitrary, size (at // least for MSW compatibility) wxSize size = sizeOrig; - if ( size.x == -1 || size.y == -1 ) - { - wxSize sizeDpy = wxGetDisplaySize(); - if ( size.x == -1 ) - size.x = sizeDpy.x / 3; - if ( size.y == -1 ) - size.y = sizeDpy.y / 5; - } + size.x = WidthDefault(size.x); + size.y = HeightDefault(size.y); wxTopLevelWindows.Append( this ); @@ -362,8 +362,9 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, m_widget = gtk_window_new( win_type ); - if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget)) && - (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) + if (m_parent && (((GTK_IS_WINDOW(m_parent->m_widget)) && + (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) || + (style & wxFRAME_FLOAT_ON_PARENT))) { gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) ); } @@ -383,13 +384,16 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS ); gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget ); - // for m_mainWidget themes - gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event", + if (m_miniEdge == 0) // wxMiniFrame has its own version. + { + // For m_mainWidget themes + gtk_signal_connect( GTK_OBJECT(m_mainWidget), "expose_event", GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); #ifndef __WXGTK20__ - gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw", + gtk_signal_connect( GTK_OBJECT(m_mainWidget), "draw", GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this ); #endif + } // m_wxwindow only represents the client area without toolbar and menubar m_wxwindow = gtk_pizza_new(); @@ -450,10 +454,15 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, // All this is for Motif Window Manager "hints" and is supposed to be // recognized by other WMs as well. if ((style & wxCAPTION) != 0) + { m_gdkDecor |= GDK_DECOR_TITLE; - if ((style & wxSYSTEM_MENU) != 0) + } + if ((style & wxCLOSE_BOX) != 0) { m_gdkFunc |= GDK_FUNC_CLOSE; + } + if ((style & wxSYSTEM_MENU) != 0) + { m_gdkDecor |= GDK_DECOR_MENU; } if ((style & wxMINIMIZE_BOX) != 0) @@ -483,7 +492,7 @@ wxTopLevelWindowGTK::~wxTopLevelWindowGTK() wxASSERT_MSG( FALSE, _T("Window still grabbed")); RemoveGrab(); } - + m_isBeingDeleted = TRUE; // it may also be GtkScrolledWindow in the case of an MDI child @@ -491,109 +500,76 @@ wxTopLevelWindowGTK::~wxTopLevelWindowGTK() { gtk_window_set_focus( GTK_WINDOW(m_widget), NULL ); } - - wxTopLevelWindows.DeleteObject( this ); - - if (wxTheApp->GetTopWindow() == this) - wxTheApp->SetTopWindow( (wxWindow*) NULL ); - - if ((wxTopLevelWindows.Number() == 0) && - (wxTheApp->GetExitOnFrameDelete())) - { - wxTheApp->ExitMainLoop(); - } } -// X11 ICCCM values for window layers -#define WIN_LAYER_NORMAL 4 -#define WIN_LAYER_ABOVE_DOCK 10 - -// X11 window manager property name -#define XA_WIN_LAYER "_WIN_LAYER" - -// X11 window manager property name atom -static Atom gs_XA_WIN_LAYER = 0; - - -static void wx_win_hints_set_layer(GtkWidget *window, int layer) -{ -#ifndef __WXGTK20__ - XEvent xev; - GdkWindowPrivate *priv; - gint prev_error; - - prev_error = gdk_error_warnings; - gdk_error_warnings = 0; - priv = (GdkWindowPrivate*)(GTK_WIDGET(window)->window); - - if (GTK_WIDGET_MAPPED(window)) - { - xev.type = ClientMessage; - xev.xclient.type = ClientMessage; - xev.xclient.window = priv->xwindow; - xev.xclient.message_type = gs_XA_WIN_LAYER; - xev.xclient.format = 32; - xev.xclient.data.l[0] = (long)layer; - xev.xclient.data.l[1] = gdk_time_get(); - - XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), False, - SubstructureNotifyMask, (XEvent*) &xev); - } - else - { - long data[1]; - - data[0] = layer; - XChangeProperty(GDK_DISPLAY(), priv->xwindow, gs_XA_WIN_LAYER, - XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); - } - gdk_error_warnings = prev_error; -#endif -} bool wxTopLevelWindowGTK::ShowFullScreen(bool show, long style ) { if (show == m_fsIsShowing) return FALSE; // return what? - if (gs_XA_WIN_LAYER == 0) - { - // Initialose X11 Atom only once - gs_XA_WIN_LAYER = XInternAtom( GDK_DISPLAY(), XA_WIN_LAYER, False ); - } - m_fsIsShowing = show; + GdkWindow *window = m_widget->window; + wxX11FullScreenMethod method = + wxGetFullScreenMethodX11((WXDisplay*)GDK_DISPLAY(), + (WXWindow)GDK_ROOT_WINDOW()); + if (show) { - m_fsSaveGdkFunc = m_gdkFunc; - m_fsSaveGdkDecor = m_gdkDecor; m_fsSaveFlag = style; GetPosition( &m_fsSaveFrame.x, &m_fsSaveFrame.y ); GetSize( &m_fsSaveFrame.width, &m_fsSaveFrame.height ); int screen_width,screen_height; wxDisplaySize( &screen_width, &screen_height ); - + gint client_x, client_y, root_x, root_y; gint width, height; + if (method != wxX11_FS_WMSPEC) + { + // don't do it always, Metacity hates it + m_fsSaveGdkFunc = m_gdkFunc; + m_fsSaveGdkDecor = m_gdkDecor; + m_gdkFunc = m_gdkDecor = 0; + gdk_window_set_decorations(window, (GdkWMDecoration)0); + gdk_window_set_functions(window, (GdkWMFunction)0); + } + gdk_window_get_origin (m_widget->window, &root_x, &root_y); gdk_window_get_geometry (m_widget->window, &client_x, &client_y, &width, &height, NULL); - - wx_win_hints_set_layer( m_widget, WIN_LAYER_ABOVE_DOCK ); gdk_window_move_resize (m_widget->window, -client_x, -client_y, screen_width + 1, screen_height + 1); + + wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(), + (WXWindow)GDK_ROOT_WINDOW(), + (WXWindow)GDK_WINDOW_XWINDOW(window), + show, &m_fsSaveFrame, method); } else { - wx_win_hints_set_layer( m_widget, WIN_LAYER_NORMAL ); - - SetSize( m_fsSaveFrame.x, m_fsSaveFrame.y, m_fsSaveFrame.width, m_fsSaveFrame.height ); + if (method != wxX11_FS_WMSPEC) + { + // don't do it always, Metacity hates it + m_gdkFunc = m_fsSaveGdkFunc; + m_gdkDecor = m_fsSaveGdkDecor; + gdk_window_set_decorations(window, (GdkWMDecoration)m_gdkDecor); + gdk_window_set_functions(window, (GdkWMFunction)m_gdkFunc); + } + + wxSetFullScreenStateX11((WXDisplay*)GDK_DISPLAY(), + (WXWindow)GDK_ROOT_WINDOW(), + (WXWindow)GDK_WINDOW_XWINDOW(window), + show, &m_fsSaveFrame, method); + + SetSize(m_fsSaveFrame.x, m_fsSaveFrame.y, + m_fsSaveFrame.width, m_fsSaveFrame.height); } + return TRUE; } @@ -671,6 +647,16 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si maxWidth = GetMaxWidth(), maxHeight = GetMaxHeight(); +#ifdef __WXGPE__ + // GPE's window manager doesn't like size hints + // at all, esp. when the user has to use the + // virtual keyboard. + minWidth = -1; + minHeight = -1; + maxWidth = -1; + maxHeight = -1; +#endif + if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth; if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; @@ -752,6 +738,16 @@ void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), maxWidth = GetMaxWidth(), maxHeight = GetMaxHeight(); +#ifdef __WXGPE__ + // GPE's window manager doesn't like size hints + // at all, esp. when the user has to use the + // virtual keyboard. + minWidth = -1; + minHeight = -1; + maxWidth = -1; + maxHeight = -1; +#endif + if ((minWidth != -1) && (m_width < minWidth)) m_width = minWidth; if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight; if ((maxWidth != -1) && (m_width > maxWidth)) m_width = maxWidth; @@ -778,7 +774,7 @@ void wxTopLevelWindowGTK::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), // Gtk-WARNING **: gtk_widget_size_allocate(): // attempt to allocate widget with width 65535 and height 600 // but I don't have time to track them all now.. - // + // // Really we need to encapulate all this height/width business and // stop any old method from ripping at the members directly and // scattering -1's without regard for who might resolve them later. @@ -845,6 +841,11 @@ void wxTopLevelWindowGTK::OnInternalIdle() if ( g_delayedFocus && wxGetTopLevelParent((wxWindow*)g_delayedFocus) == this ) { + wxLogTrace(_T("focus"), + _T("Setting focus from wxTLW::OnIdle() to %s(%s)"), + g_delayedFocus->GetClassInfo()->GetClassName(), + g_delayedFocus->GetLabel().c_str()); + g_delayedFocus->SetFocus(); g_delayedFocus = NULL; } @@ -904,9 +905,16 @@ void wxTopLevelWindowGTK::SetIcons( const wxIconBundle &icons ) // frame state: maximized/iconized/normal // ---------------------------------------------------------------------------- -void wxTopLevelWindowGTK::Maximize(bool WXUNUSED(maximize)) +void wxTopLevelWindowGTK::Maximize(bool maximize) { +#ifdef __WXGTK20__ + if (maximize) + gtk_window_maximize( GTK_WINDOW( m_widget ) ); + else + gtk_window_unmaximize( GTK_WINDOW( m_widget ) ); +#else wxFAIL_MSG( _T("not implemented") ); +#endif } bool wxTopLevelWindowGTK::IsMaximized() const @@ -919,11 +927,22 @@ bool wxTopLevelWindowGTK::IsMaximized() const void wxTopLevelWindowGTK::Restore() { +#ifdef __GTK20__ + // "Present" seems similar enough to "restore" + gtk_window_present( GTK_WINDOW( m_widget ) ); +#else wxFAIL_MSG( _T("not implemented") ); +#endif } void wxTopLevelWindowGTK::Iconize( bool iconize ) { +#ifdef __WXGTK20__ + if (iconize) + gtk_window_iconify( GTK_WINDOW( m_widget ) ); + else + gtk_window_deiconify( GTK_WINDOW( m_widget ) ); +#else if (iconize) { GdkWindow *window = m_widget->window; @@ -935,6 +954,7 @@ void wxTopLevelWindowGTK::Iconize( bool iconize ) GDK_WINDOW_XWINDOW( window ), DefaultScreen( GDK_DISPLAY() ) ); } +#endif } bool wxTopLevelWindowGTK::IsIconized() const @@ -971,4 +991,46 @@ void wxTopLevelWindowGTK::RemoveGrab() } } + +// helper +static bool do_shape_combine_region(GdkWindow* window, const wxRegion& region) +{ + if (window) + { + if (region.IsEmpty()) + { + gdk_window_shape_combine_mask(window, NULL, 0, 0); + } + else + { +#ifdef __WXGTK20__ + gdk_window_shape_combine_region(window, region.GetRegion(), 0, 0); +#else + wxBitmap bmp = region.ConvertToBitmap(); + bmp.SetMask(new wxMask(bmp, *wxBLACK)); + GdkBitmap* mask = bmp.GetMask()->GetBitmap(); + gdk_window_shape_combine_mask(window, mask, 0, 0); +#endif + return TRUE; + } + } + return FALSE; +} + + +bool wxTopLevelWindowGTK::SetShape(const wxRegion& region) +{ + wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), FALSE, + _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); + + GdkWindow *window = NULL; + if (m_wxwindow) + { + window = GTK_PIZZA(m_wxwindow)->bin_window; + do_shape_combine_region(window, region); + } + window = m_widget->window; + return do_shape_combine_region(window, region); +} + // vi:sts=4:sw=4:et