X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7e3edf927b261e1af8c01fbb4ff2b04858881df4..20833aaa0a5e6327596eda231bdf835754bb3be7:/src/gtk/toplevel.cpp diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index db1c6404dd..3ee1c1efe0 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -7,6 +7,9 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + // ============================================================================ // declarations // ============================================================================ @@ -15,30 +18,23 @@ // headers // ---------------------------------------------------------------------------- -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - #ifdef __VMS #define XIconifyWindow XICONIFYWINDOW #endif -#include "wx/defs.h" - #include "wx/toplevel.h" -#include "wx/log.h" -#include "wx/dialog.h" -#include "wx/control.h" -#include "wx/app.h" -#include "wx/dcclient.h" + +#ifndef WX_PRECOMP + #include "wx/frame.h" + #include "wx/icon.h" + #include "wx/log.h" + #include "wx/app.h" +#endif + #include "wx/gtk/private.h" -#include "wx/timer.h" -#include "wx/settings.h" #include "wx/evtloop.h" -#include -#include #include -#include #include #include "wx/gtk/win_gtk.h" @@ -52,8 +48,6 @@ // data // ---------------------------------------------------------------------------- -extern wxList wxPendingDelete; - extern int g_openDialogs; extern wxWindowGTK *g_delayedFocus; @@ -96,7 +90,7 @@ static void wxgtk_window_set_urgency_hint (GtkWindow *win, static gboolean gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK *win ) { -#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,7,0) +#if GTK_CHECK_VERSION(2,7,0) if(!gtk_check_version(2,7,0)) gtk_window_set_urgency_hint(GTK_WINDOW( win->m_widget ), FALSE); else @@ -117,8 +111,7 @@ static gboolean gtk_frame_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win ) { - if (g_isIdle) - wxapp_install_idle_handler(); + // don't need to install idle handler, its done from "event" signal switch ( g_sendActivateEvent ) { @@ -146,7 +139,7 @@ static gboolean gtk_frame_focus_in_callback( GtkWidget *widget, g_source_remove( win->m_urgency_hint ); // no break, fallthrough to remove hint too case -1: -#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,7,0) +#if GTK_CHECK_VERSION(2,7,0) if(!gtk_check_version(2,7,0)) gtk_window_set_urgency_hint(GTK_WINDOW( widget ), FALSE); else @@ -179,8 +172,7 @@ static gboolean gtk_frame_focus_out_callback( GtkWidget *widget, GdkEventFocus *WXUNUSED(gdk_event), wxTopLevelWindowGTK *win ) { - if (g_isIdle) - wxapp_install_idle_handler(); + // don't need to install idle handler, its done from "event" signal // if the focus goes out of our app alltogether, OnIdle() will send // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset @@ -216,7 +208,6 @@ static gboolean gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WX wxapp_install_idle_handler(); // This disables GTK's tab traversal - g_signal_stop_emission_by_name (widget, "focus"); return TRUE; } } @@ -237,10 +228,10 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* if ((win->m_width != alloc->width) || (win->m_height != alloc->height)) { /* - wxPrintf( "OnSize from " ); + wxPrintf( wxT("gtk_frame_size_callback from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)alloc->x, + wxPrintf( wxT(" %d %d %d %d\n"), (int)alloc->x, (int)alloc->y, (int)alloc->width, (int)alloc->height ); @@ -263,8 +254,7 @@ gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win ) { - if (g_isIdle) - wxapp_install_idle_handler(); + // don't need to install idle handler, its done from "event" signal if (win->IsEnabled() && (g_openDialogs == 0 || (win->GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) || @@ -286,8 +276,7 @@ gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win ) { - if (g_isIdle) - wxapp_install_idle_handler(); + // don't need to install idle handler, its done from "event" signal if (!win->m_hasVMT || !win->IsShown()) return FALSE; @@ -435,9 +424,6 @@ static void wxInsertChildInTopLevelWindow( wxTopLevelWindowGTK* parent, wxWindow child->m_width, child->m_height ); } - - // resize on OnInternalIdle - parent->GtkUpdateSize(); } // ---------------------------------------------------------------------------- @@ -556,8 +542,10 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, } #endif +#if 0 if (!name.empty()) - gtk_window_set_wmclass( GTK_WINDOW(m_widget), wxGTK_CONV( name ), wxGTK_CONV( name ) ); + gtk_window_set_role( GTK_WINDOW(m_widget), wxGTK_CONV( name ) ); +#endif gtk_window_set_title( GTK_WINDOW(m_widget), wxGTK_CONV( title ) ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); @@ -626,12 +614,21 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, G_CALLBACK (gtk_frame_focus_out_callback), this); // decorations - if ((m_miniEdge > 0) || (style & wxSIMPLE_BORDER) || (style & wxNO_BORDER)) + if ((style & wxSIMPLE_BORDER) || (style & wxNO_BORDER)) { m_gdkDecor = 0; m_gdkFunc = 0; } else + if (m_miniEdge > 0) + { + m_gdkDecor = 0; + m_gdkFunc = 0; + + if ((style & wxRESIZE_BORDER) != 0) + m_gdkFunc |= GDK_FUNC_RESIZE; + } + else { m_gdkDecor = (long) GDK_DECOR_BORDER; m_gdkFunc = (long) GDK_FUNC_MOVE; @@ -674,7 +671,7 @@ wxTopLevelWindowGTK::~wxTopLevelWindowGTK() { if (m_grabbed) { - wxASSERT_MSG( false, _T("Window still grabbed")); + wxFAIL_MSG(_T("Window still grabbed")); RemoveGrab(); } @@ -793,6 +790,9 @@ bool wxTopLevelWindowGTK::Show( bool show ) { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); + if (show == IsShown()) + return true; + if (show && !m_sizeSet) { /* by calling GtkOnSize here, we don't have to call @@ -803,8 +803,11 @@ bool wxTopLevelWindowGTK::Show( bool show ) GtkOnSize( m_x, m_y, m_width, m_height ); } - if (show) - gtk_widget_set_uposition( m_widget, m_x, m_y ); + // This seems no longer to be needed and the call + // itself is deprecated. + // + //if (show) + // gtk_widget_set_uposition( m_widget, m_x, m_y ); return wxWindow::Show( show ); } @@ -910,16 +913,20 @@ void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const { wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") ); - wxWindow::DoGetClientSize( width, height ); if (height) { + *height = m_height; + // mini edge *height -= m_miniEdge*2 + m_miniTitle; } if (width) { + *width = m_width; + *width -= m_miniEdge*2; } + } void wxTopLevelWindowGTK::DoSetClientSize( int width, int height ) @@ -1264,7 +1271,7 @@ void wxTopLevelWindowGTK::RequestUserAttention(int flags) } } -#if defined(__WXGTK20__) && GTK_CHECK_VERSION(2,7,0) +#if GTK_CHECK_VERSION(2,7,0) if(!gtk_check_version(2,7,0)) gtk_window_set_urgency_hint(GTK_WINDOW( m_widget ), new_hint_value); else @@ -1298,3 +1305,71 @@ void wxTopLevelWindowGTK::SetWindowStyleFlag( long style ) } #endif // GTK+ 2.2 } + +#include + +/* Get the X Window between child and the root window. + This should usually be the WM managed XID */ +static Window wxGetTopmostWindowX11(Display *dpy, Window child) +{ + Window root, parent; + Window* children; + unsigned int nchildren; + + XQueryTree(dpy, child, &root, &parent, &children, &nchildren); + XFree(children); + + while (parent != root) { + child = parent; + XQueryTree(dpy, child, &root, &parent, &children, &nchildren); + XFree(children); + } + + return child; +} + +bool wxTopLevelWindowGTK::SetTransparent(wxByte alpha) +{ + if (!m_widget || !m_widget->window) + return false; + + Display* dpy = GDK_WINDOW_XDISPLAY (m_widget->window); + // We need to get the X Window that has the root window as the immediate parent + // and m_widget->window as a child. This should be the X Window that the WM manages and + // from which the opacity property is checked from. + Window win = wxGetTopmostWindowX11(dpy, GDK_WINDOW_XID (m_widget->window)); + + unsigned int opacity = alpha * 0x1010101; + + // Using pure Xlib to not have a GTK version check mess due to gtk2.0 not having GdkDisplay + if (alpha == 0xff) + XDeleteProperty(dpy, win, XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False)); + else + XChangeProperty(dpy, win, XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False), + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) &opacity, 1L); + XSync(dpy, False); + return true; +} + +bool wxTopLevelWindowGTK::CanSetTransparent() +{ +#if GTK_CHECK_VERSION(2,10,0) + if (!gtk_check_version(2,10,0)) + { + if (gtk_widget_is_composited (m_widget)) + return true; + } + else +#endif // In case of lower versions than gtk+-2.10.0 we could look for _NET_WM_CM_Sn ourselves + { + return false; + } + +#if 0 // Don't be optimistic here for the sake of wxAUI + int opcode, event, error; + // Check for the existence of a RGBA visual instead? + return XQueryExtension(gdk_x11_get_default_xdisplay (), + "Composite", &opcode, &event, &error); +#endif +}