]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/toplevel.cpp
we're always compositing
[wxWidgets.git] / src / gtk / toplevel.cpp
index 439133d152c7e71da87c3e776ee5e584e69e79d2..467d67ab53d7c4578b71e3982137224956e33970 100644 (file)
@@ -7,6 +7,9 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
 // ============================================================================
 // declarations
 // ============================================================================
 // 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 <glib.h>
 // XA_CARDINAL
 #include <X11/Xatom.h>
 
-// ----------------------------------------------------------------------------
-// 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 <X11/Xlib.h>
+
+/* 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
+}