changeset 5042:5244f372da58

RT-26429 Gtk: Ensemble doesn't work after minimize/maximize on 2.2.5 / Ubuntu
author Alexander Zvegintsev
date Wed, 11 Sep 2013 14:29:25 +0400
parents 81798bc43ce4
children 5caeaa91af23
files modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkView.java modules/graphics/src/main/native-glass/gtk/GlassView.cpp modules/graphics/src/main/native-glass/gtk/glass_window.cpp modules/graphics/src/main/native-glass/gtk/glass_window.h
diffstat 4 files changed, 107 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkView.java	Wed Sep 11 10:46:05 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkView.java	Wed Sep 11 14:29:25 2013 +0400
@@ -70,10 +70,10 @@
     protected native void _scheduleRepaint(long ptr);
 
     @Override
-    protected native void _begin(long ptr);
+    protected void _begin(long ptr) {}
 
     @Override
-    protected native void _end(long ptr);
+    protected void _end(long ptr) {}
 
     @Override 
     protected void _uploadPixels(long ptr, Pixels pixels) {
--- a/modules/graphics/src/main/native-glass/gtk/GlassView.cpp	Wed Sep 11 10:46:05 2013 +0200
+++ b/modules/graphics/src/main/native-glass/gtk/GlassView.cpp	Wed Sep 11 14:29:25 2013 +0400
@@ -155,27 +155,6 @@
 
 /*
  * Class:     com_sun_glass_ui_gtk_GtkView
- * Method:    _begin
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_com_sun_glass_ui_gtk_GtkView__1begin
-  (JNIEnv * env, jobject obj, jlong ptr)
-{
-    // No need to lock, done automatically by GDK
-}
-
-/*
- * Class:     com_sun_glass_ui_gtk_GtkView
- * Method:    _end
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_com_sun_glass_ui_gtk_GtkView__1end
-  (JNIEnv * env, jobject obj, jlong ptr)
-{
-}
-
-/*
- * Class:     com_sun_glass_ui_gtk_GtkView
  * Method:    _uploadPixelsDirect
  * Signature: (JLjava/nio/Buffer;II)V
  */
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Wed Sep 11 10:46:05 2013 +0200
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Wed Sep 11 14:29:25 2013 +0400
@@ -48,6 +48,8 @@
 WindowContext * WindowContextBase::sm_grab_window = NULL;
 WindowContext * WindowContextBase::sm_mouse_drag_window = NULL;
 
+GdkAtom atom_net_wm_state = gdk_atom_intern_static_string("_NET_WM_STATE");
+
 GdkWindow* WindowContextBase::get_gdk_window(){
     return gdk_window;
 }
@@ -70,6 +72,55 @@
     }
 }
 
+void WindowContextBase::notify_state(jint glass_state) {
+    if (glass_state == com_sun_glass_events_WindowEvent_RESTORE) {
+        if (is_maximized) {
+            glass_state = com_sun_glass_events_WindowEvent_MAXIMIZE;
+        }
+
+        int w, h;
+        glass_gdk_window_get_size(gdk_window, &w, &h);
+        if (jview) {
+            mainEnv->CallVoidMethod(jview,
+                    jViewNotifyRepaint,
+                    0, 0, w, h);
+            CHECK_JNI_EXCEPTION(mainEnv);
+        }
+    }
+
+    if (jwindow) {
+       mainEnv->CallVoidMethod(jwindow,
+               jGtkWindowNotifyStateChanged,
+               glass_state);
+       CHECK_JNI_EXCEPTION(mainEnv);
+    }
+}
+
+void WindowContextBase::process_state(GdkEventWindowState* event) {
+    if (event->changed_mask & 
+            (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_MAXIMIZED)) {
+        
+        if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) {
+            is_iconified = event->new_window_state & GDK_WINDOW_STATE_ICONIFIED;
+        } 
+        if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
+            is_maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
+        }
+        
+        jint stateChangeEvent;
+
+        if (is_iconified) {
+            stateChangeEvent = com_sun_glass_events_WindowEvent_MINIMIZE;
+        } else if (is_maximized) {
+            stateChangeEvent = com_sun_glass_events_WindowEvent_MAXIMIZE;
+        } else {
+            stateChangeEvent = com_sun_glass_events_WindowEvent_RESTORE;
+        }
+
+        notify_state(stateChangeEvent);
+    }
+}
+
 void WindowContextBase::process_focus(GdkEventFocus* event) {
     if (!event->in && WindowContextBase::sm_mouse_drag_window == this) {
         ungrab_mouse_drag_focus();
@@ -753,8 +804,46 @@
     windowGeometry->refy = newValue;
 }
 
+void WindowContextTop::process_net_wm_property() {
+    // Workaround for https://bugs.launchpad.net/unity/+bug/998073
+
+    static GdkAtom atom_atom = gdk_atom_intern_static_string("ATOM");
+    static GdkAtom atom_net_wm_state_hidden = gdk_atom_intern_static_string("_NET_WM_STATE_HIDDEN");
+    
+    gint length;
+
+    GdkAtom* atoms = NULL;
+
+    if (gdk_property_get(gdk_window, atom_net_wm_state, atom_atom,
+            0, G_MAXLONG, FALSE, NULL, NULL, &length, (guchar**) &atoms)) {
+
+        gint i = 0;
+        bool is_hidden = false;
+        while (i < length) {
+            if (atom_net_wm_state_hidden == atoms[i]) {
+                is_hidden = true;
+                break;
+            }
+
+            i++;
+        }
+
+        g_free(atoms);
+
+        if (is_iconified != is_hidden) {
+            is_iconified = is_hidden;
+
+            notify_state((is_hidden) 
+                            ? com_sun_glass_events_WindowEvent_MINIMIZE 
+                            : com_sun_glass_events_WindowEvent_RESTORE);
+        }
+    }
+}
+
 void WindowContextTop::process_property_notify(GdkEventProperty* event) {
-    if (event->atom == get_net_frame_extents_atom() &&
+    if (event->atom == atom_net_wm_state && event->window == gdk_window) {
+        process_net_wm_property();
+    } else if (event->atom == get_net_frame_extents_atom() &&
             event->window == gdk_window) {
         int top, left, bottom, right;
         if (get_frame_extents_property(&top, &left, &bottom, &right)) {
@@ -855,12 +944,14 @@
     }
     if (jwindow) {
         mainEnv->CallVoidMethod(jwindow, jWindowNotifyResize,
-                com_sun_glass_events_WindowEvent_RESIZE,
+                (is_maximized)
+                    ? com_sun_glass_events_WindowEvent_MAXIMIZE
+                    : com_sun_glass_events_WindowEvent_RESIZE,
                 geometry.current_width,
                 geometry.current_height);
         CHECK_JNI_EXCEPTION(mainEnv)
 
-            mainEnv->CallVoidMethod(jwindow, jWindowNotifyMove, x, y);
+        mainEnv->CallVoidMethod(jwindow, jWindowNotifyMove, x, y);
         CHECK_JNI_EXCEPTION(mainEnv)
     }
 
@@ -1082,38 +1173,6 @@
             windowChanges);
 }
 
-void WindowContextTop::process_state(GdkEventWindowState *event) {
-    if (event->changed_mask & (GDK_WINDOW_STATE_ICONIFIED
-            | GDK_WINDOW_STATE_MAXIMIZED)) {
-        jint stateChangeEvent;
-
-        if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_MINIMIZE;
-        } else if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_MAXIMIZE;
-        } else {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_RESTORE;
-
-            int w, h;
-            glass_gdk_window_get_size(gdk_window, &w, &h);
-            if (jview) {
-                mainEnv->CallVoidMethod(jview,
-                        jViewNotifyRepaint,
-                        0, 0, w, h);
-                CHECK_JNI_EXCEPTION(mainEnv);
-            }
-        }
-
-        if (jwindow) {
-            mainEnv->CallVoidMethod(jwindow,
-                    jGtkWindowNotifyStateChanged,
-                    stateChangeEvent);
-            CHECK_JNI_EXCEPTION(mainEnv);
-        }
-    }
-}
-
-
 void WindowContextTop::applyShapeMask(cairo_surface_t* cairo_surface, uint width, uint height)
 {
     if (frame_type != TRANSPARENT) {
@@ -1169,6 +1228,7 @@
 }
 
 void WindowContextTop::set_minimized(bool minimize) {
+    is_iconified = minimize;
     if (minimize) {
         gtk_window_iconify(GTK_WINDOW(gtk_widget));
     } else {
@@ -1176,6 +1236,7 @@
     }
 }
 void WindowContextTop::set_maximized(bool maximize) {
+    is_maximized = maximize;
     if (maximize) {
         gtk_window_maximize(GTK_WINDOW(gtk_widget));
     } else {
@@ -1352,37 +1413,6 @@
     }
 }
 
-void WindowContextPlug::process_state(GdkEventWindowState *event) {
-    if (event->changed_mask & (GDK_WINDOW_STATE_ICONIFIED
-            | GDK_WINDOW_STATE_MAXIMIZED)) {
-        jint stateChangeEvent;
-
-        if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_MINIMIZE;
-        } else if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_MAXIMIZE;
-        } else {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_RESTORE;
-
-            int w, h;
-            glass_gdk_window_get_size(gdk_window, &w, &h);
-            if (jview) {
-                mainEnv->CallVoidMethod(jview,
-                        jViewNotifyRepaint,
-                        0, 0, w, h);
-                CHECK_JNI_EXCEPTION(mainEnv)
-            }
-        }
-
-        if (jwindow) {
-            mainEnv->CallVoidMethod(jwindow,
-                    jGtkWindowNotifyStateChanged,
-                    stateChangeEvent);
-            CHECK_JNI_EXCEPTION(mainEnv);
-        }
-    }
-}
-
 bool WindowContextPlug::set_view(jobject view) {
     // probably never called for applet window
     if (jview) {
@@ -1550,37 +1580,6 @@
     }
 }
 
-void WindowContextChild::process_state(GdkEventWindowState *event) {
-    if (event->changed_mask & (GDK_WINDOW_STATE_ICONIFIED
-            | GDK_WINDOW_STATE_MAXIMIZED)) {
-        jint stateChangeEvent;
-
-        if (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_MINIMIZE;
-        } else if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_MAXIMIZE;
-        } else {
-            stateChangeEvent = com_sun_glass_events_WindowEvent_RESTORE;
-
-            int w, h;
-            glass_gdk_window_get_size(gdk_window, &w, &h);
-            if (jview) {
-                mainEnv->CallVoidMethod(jview,
-                        jViewNotifyRepaint,
-                        0, 0, w, h);
-            }
-            CHECK_JNI_EXCEPTION(mainEnv);
-        }
-
-        if (jwindow) {
-            mainEnv->CallVoidMethod(jwindow,
-                    jGtkWindowNotifyStateChanged,
-                    stateChangeEvent);
-            CHECK_JNI_EXCEPTION(mainEnv);
-        }
-    }
-}
-
 bool WindowContextChild::set_view(jobject view) {
     if (jview) {
         mainEnv->DeleteGlobalRef(jview);
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.h	Wed Sep 11 10:46:05 2013 +0200
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.h	Wed Sep 11 14:29:25 2013 +0400
@@ -152,6 +152,8 @@
     virtual void process_mouse_cross(GdkEventCrossing*) = 0;
     virtual void process_key(GdkEventKey*) = 0;
     virtual void process_state(GdkEventWindowState*) = 0;
+    
+    virtual void notify_state(jint) = 0;
 
     virtual void add_child(WindowContextTop* child) = 0;
     virtual void remove_child(WindowContextTop* child) = 0;
@@ -190,6 +192,8 @@
     GtkWidget* gtk_widget;
     GdkWindow* gdk_window;
 
+    bool is_iconified;
+    bool is_maximized;
     bool is_mouse_entered;
 
     /*
@@ -246,6 +250,9 @@
     void process_mouse_scroll(GdkEventScroll*);
     void process_mouse_cross(GdkEventCrossing*);
     void process_key(GdkEventKey*);
+    void process_state(GdkEventWindowState*);
+
+    void notify_state(jint);
 
     int getEmbeddedX() { return 0; }
     int getEmbeddedY() { return 0; }
@@ -289,7 +296,6 @@
     void process_property_notify(GdkEventProperty*) {}
     void process_configure(GdkEventConfigure*);
     void process_gtk_configure(GdkEventConfigure*);
-    void process_state(GdkEventWindowState*);
 
     void applyShapeMask(cairo_surface_t*, uint width, uint height) {}
     GtkWindow *get_gtk_window(); // TODO, get window from parent
@@ -333,7 +339,6 @@
     void set_gravity(float, float) {}
     void process_property_notify(GdkEventProperty*) {}
     void process_configure(GdkEventConfigure*);
-    void process_state(GdkEventWindowState*);
     void process_destroy();
     void set_visible(bool visible);
 
@@ -376,8 +381,9 @@
     void process_map();
     void process_property_notify(GdkEventProperty*);
     void process_configure(GdkEventConfigure*);
-    void process_state(GdkEventWindowState*);
     void process_destroy();
+    void process_net_wm_property();
+
     WindowFrameExtents get_frame_extents();
 
     void set_minimized(bool);