X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8e729eb44b9d88850799d9c3748ada6cfefd953e..b86db821bf1d67c15f87c5343134170a39a363d1:/src/gtk/toplevel.cpp diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 439133d152..467d67ab53 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,24 +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/log.h" + #include "wx/app.h" + #include "wx/dcclient.h" + #include "wx/dialog.h" + #include "wx/timer.h" + #include "wx/settings.h" + #include "wx/control.h" +#endif + #include "wx/gtk/private.h" -#include "wx/timer.h" -#include "wx/settings.h" #include "wx/evtloop.h" #include @@ -48,19 +50,10 @@ // XA_CARDINAL #include -// ---------------------------------------------------------------------------- -// idle system -// ---------------------------------------------------------------------------- - -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; - // ---------------------------------------------------------------------------- // data // ---------------------------------------------------------------------------- -extern wxList wxPendingDelete; - extern int g_openDialogs; extern wxWindowGTK *g_delayedFocus; @@ -103,7 +96,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 @@ -120,7 +113,7 @@ static gboolean gtk_frame_urgency_timer_callback( wxTopLevelWindowGTK *win ) //----------------------------------------------------------------------------- extern "C" { -static gint gtk_frame_focus_in_callback( GtkWidget *widget, +static gboolean gtk_frame_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win ) { @@ -153,7 +146,7 @@ static gint 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 @@ -182,7 +175,7 @@ static gint gtk_frame_focus_in_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_frame_focus_out_callback( GtkWidget *widget, +static gboolean gtk_frame_focus_out_callback( GtkWidget *widget, GdkEventFocus *WXUNUSED(gdk_event), wxTopLevelWindowGTK *win ) { @@ -217,7 +210,7 @@ static gint gtk_frame_focus_out_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) ) +static gboolean gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) ) { if (g_isIdle) wxapp_install_idle_handler(); @@ -265,7 +258,10 @@ static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* //----------------------------------------------------------------------------- extern "C" { -static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxTopLevelWindowGTK *win ) +static gboolean +gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), + GdkEvent *WXUNUSED(event), + wxTopLevelWindowGTK *win ) { if (g_isIdle) wxapp_install_idle_handler(); @@ -285,8 +281,10 @@ static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WX //----------------------------------------------------------------------------- extern "C" { -static gint -gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxTopLevelWindowGTK *win ) +static gboolean +gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), + GdkEventConfigure *WXUNUSED(event), + wxTopLevelWindowGTK *win ) { if (g_isIdle) wxapp_install_idle_handler(); @@ -380,7 +378,10 @@ gtk_frame_unmap_callback( GtkWidget * WXUNUSED(widget), //----------------------------------------------------------------------------- extern "C" { -static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) +static gboolean +gtk_window_expose_callback( GtkWidget *widget, + GdkEventExpose *gdk_event, + wxWindow *win ) { GtkPizza *pizza = GTK_PIZZA(widget); @@ -555,8 +556,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 ); @@ -619,9 +622,9 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, G_CALLBACK (gtk_frame_focus_callback), this); // activation - g_signal_connect (m_widget, "focus_in_event", + g_signal_connect_after (m_widget, "focus_in_event", G_CALLBACK (gtk_frame_focus_in_callback), this); - g_signal_connect (m_widget, "focus_out_event", + g_signal_connect_after (m_widget, "focus_out_event", G_CALLBACK (gtk_frame_focus_out_callback), this); // decorations @@ -673,7 +676,7 @@ wxTopLevelWindowGTK::~wxTopLevelWindowGTK() { if (m_grabbed) { - wxASSERT_MSG( false, _T("Window still grabbed")); + wxFAIL_MSG(_T("Window still grabbed")); RemoveGrab(); } @@ -792,6 +795,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 @@ -802,8 +808,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 ); } @@ -1263,7 +1272,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 @@ -1273,8 +1282,10 @@ void wxTopLevelWindowGTK::RequestUserAttention(int flags) void wxTopLevelWindowGTK::SetWindowStyleFlag( long style ) { +#if defined(__WXGTK24__) || GTK_CHECK_VERSION(2,2,0) // Store which styles were changed long styleChanges = style ^ m_windowStyle; +#endif // Process wxWindow styles. This also updates the internal variable // Therefore m_windowStyle bits carry now the _new_ style values @@ -1295,3 +1306,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 +}