modules/graphics/src/main/native-glass/gtk/glass_window.cpp

Print this page




 103             (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_MAXIMIZED)) {
 104         
 105         if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) {
 106             is_iconified = event->new_window_state & GDK_WINDOW_STATE_ICONIFIED;
 107         } 
 108         if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
 109             is_maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
 110         }
 111         
 112         jint stateChangeEvent;
 113 
 114         if (is_iconified) {
 115             stateChangeEvent = com_sun_glass_events_WindowEvent_MINIMIZE;
 116         } else if (is_maximized) {
 117             stateChangeEvent = com_sun_glass_events_WindowEvent_MAXIMIZE;
 118         } else {
 119             stateChangeEvent = com_sun_glass_events_WindowEvent_RESTORE;
 120         }
 121 
 122         notify_state(stateChangeEvent);


 123     } 
 124 }
 125 
 126 void WindowContextBase::process_focus(GdkEventFocus* event) {
 127     if (!event->in && WindowContextBase::sm_mouse_drag_window == this) {
 128         ungrab_mouse_drag_focus();
 129     }
 130     if (!event->in && WindowContextBase::sm_grab_window == this) {
 131         ungrab_focus();
 132     }
 133     if (jwindow) {
 134         if (!event->in || isEnabled()) {
 135             mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocus,
 136                     event->in ? com_sun_glass_events_WindowEvent_FOCUS_GAINED : com_sun_glass_events_WindowEvent_FOCUS_LOST);
 137             CHECK_JNI_EXCEPTION(mainEnv)
 138         } else {
 139             mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocusDisabled);
 140             CHECK_JNI_EXCEPTION(mainEnv)
 141         }
 142     }


 802         newValue += geometry_get_window_width(windowGeometry)
 803                 * windowGeometry->gravity_x;
 804     }
 805     windowGeometry->refx = newValue;
 806 }
 807 
 808 static void geometry_set_window_y(WindowGeometry *windowGeometry, int value) {
 809     float newValue = value;
 810     if (windowGeometry->gravity_y != 0) {
 811         newValue += geometry_get_window_height(windowGeometry)
 812                 * windowGeometry->gravity_y;
 813     }
 814     windowGeometry->refy = newValue;
 815 }
 816 
 817 void WindowContextTop::process_net_wm_property() {
 818     // Workaround for https://bugs.launchpad.net/unity/+bug/998073
 819 
 820     static GdkAtom atom_atom = gdk_atom_intern_static_string("ATOM");
 821     static GdkAtom atom_net_wm_state_hidden = gdk_atom_intern_static_string("_NET_WM_STATE_HIDDEN");

 822     
 823     gint length;
 824 
 825     GdkAtom* atoms = NULL;
 826 
 827     if (gdk_property_get(gdk_window, atom_net_wm_state, atom_atom,
 828             0, G_MAXLONG, FALSE, NULL, NULL, &length, (guchar**) &atoms)) {
 829 
 830         gint i = 0;
 831         bool is_hidden = false;

 832         while (i < length) {
 833             if (atom_net_wm_state_hidden == atoms[i]) {
 834                 is_hidden = true;
 835                 break;

 836             }
 837 
 838             i++;
 839         }
 840 
 841         g_free(atoms);
 842 
 843         if (is_iconified != is_hidden) {
 844             is_iconified = is_hidden;
 845 
 846             notify_state((is_hidden)
 847                     ? com_sun_glass_events_WindowEvent_MINIMIZE
 848                     : com_sun_glass_events_WindowEvent_RESTORE);
 849         }


 850     }
 851 }
 852 
 853 void WindowContextTop::process_property_notify(GdkEventProperty* event) {
 854     if (event->atom == atom_net_wm_state && event->window == gdk_window) {
 855         process_net_wm_property();
 856     } else if (event->atom == get_net_frame_extents_atom() &&
 857             event->window == gdk_window) {
 858         int top, left, bottom, right;
 859         if (get_frame_extents_property(&top, &left, &bottom, &right)) {
 860             int oldX = geometry_get_window_x(&geometry);
 861             int oldY = geometry_get_window_y(&geometry);
 862             int oldWidth = geometry_get_content_width(&geometry);
 863             int oldHeight = geometry_get_content_height(&geometry);
 864 
 865             bool updateWindowConstraints = geometry.extents.top != top
 866                     || geometry.extents.left != left
 867                     || geometry.extents.bottom != bottom
 868                     || geometry.extents.right != right;
 869 


1323 
1324 void WindowContextTop::update_ontop_tree(bool on_top) {
1325     bool effective_on_top = on_top || this->on_top;
1326     gtk_window_set_keep_above(GTK_WINDOW(gtk_widget), effective_on_top ? TRUE : FALSE);
1327     for (std::set<WindowContextTop*>::iterator it = children.begin(); it != children.end(); ++it) {
1328         (*it)->update_ontop_tree(effective_on_top);
1329     }
1330 }
1331 
1332 bool WindowContextTop::on_top_inherited() {
1333     WindowContext* o = owner;
1334     while (o) {
1335         WindowContextTop* topO = dynamic_cast<WindowContextTop*>(o);
1336         if (!topO) break;
1337         if (topO->on_top) {
1338             return true;
1339         }
1340         o = topO->owner;
1341     }
1342     return false;

























1343 }
1344 
1345 void WindowContextTop::set_level(int level) {
1346     if (level == com_sun_glass_ui_Window_Level_NORMAL) {
1347         on_top = false;
1348     } else if (level == com_sun_glass_ui_Window_Level_FLOATING
1349             || level == com_sun_glass_ui_Window_Level_TOPMOST) {
1350         on_top = true;
1351     }
1352     // We need to emulate always on top behaviour on child windows
1353 
1354     if (!on_top_inherited()) {
1355         update_ontop_tree(on_top);
1356     }
1357 }
1358 
1359 void WindowContextTop::set_owner(WindowContext * owner_ctx) {
1360     owner = owner_ctx;
1361 }
1362 




 103             (GDK_WINDOW_STATE_ICONIFIED | GDK_WINDOW_STATE_MAXIMIZED)) {
 104         
 105         if (event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) {
 106             is_iconified = event->new_window_state & GDK_WINDOW_STATE_ICONIFIED;
 107         } 
 108         if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
 109             is_maximized = event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED;
 110         }
 111         
 112         jint stateChangeEvent;
 113 
 114         if (is_iconified) {
 115             stateChangeEvent = com_sun_glass_events_WindowEvent_MINIMIZE;
 116         } else if (is_maximized) {
 117             stateChangeEvent = com_sun_glass_events_WindowEvent_MAXIMIZE;
 118         } else {
 119             stateChangeEvent = com_sun_glass_events_WindowEvent_RESTORE;
 120         }
 121 
 122         notify_state(stateChangeEvent);
 123     } else if (event->changed_mask & GDK_WINDOW_STATE_ABOVE) {
 124         notify_on_top( event->new_window_state & GDK_WINDOW_STATE_ABOVE);
 125     } 
 126 }
 127 
 128 void WindowContextBase::process_focus(GdkEventFocus* event) {
 129     if (!event->in && WindowContextBase::sm_mouse_drag_window == this) {
 130         ungrab_mouse_drag_focus();
 131     }
 132     if (!event->in && WindowContextBase::sm_grab_window == this) {
 133         ungrab_focus();
 134     }
 135     if (jwindow) {
 136         if (!event->in || isEnabled()) {
 137             mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocus,
 138                     event->in ? com_sun_glass_events_WindowEvent_FOCUS_GAINED : com_sun_glass_events_WindowEvent_FOCUS_LOST);
 139             CHECK_JNI_EXCEPTION(mainEnv)
 140         } else {
 141             mainEnv->CallVoidMethod(jwindow, jWindowNotifyFocusDisabled);
 142             CHECK_JNI_EXCEPTION(mainEnv)
 143         }
 144     }


 804         newValue += geometry_get_window_width(windowGeometry)
 805                 * windowGeometry->gravity_x;
 806     }
 807     windowGeometry->refx = newValue;
 808 }
 809 
 810 static void geometry_set_window_y(WindowGeometry *windowGeometry, int value) {
 811     float newValue = value;
 812     if (windowGeometry->gravity_y != 0) {
 813         newValue += geometry_get_window_height(windowGeometry)
 814                 * windowGeometry->gravity_y;
 815     }
 816     windowGeometry->refy = newValue;
 817 }
 818 
 819 void WindowContextTop::process_net_wm_property() {
 820     // Workaround for https://bugs.launchpad.net/unity/+bug/998073
 821 
 822     static GdkAtom atom_atom = gdk_atom_intern_static_string("ATOM");
 823     static GdkAtom atom_net_wm_state_hidden = gdk_atom_intern_static_string("_NET_WM_STATE_HIDDEN");
 824     static GdkAtom atom_net_wm_state_above = gdk_atom_intern_static_string("_NET_WM_STATE_ABOVE");
 825     
 826     gint length;
 827 
 828     GdkAtom* atoms = NULL;
 829 
 830     if (gdk_property_get(gdk_window, atom_net_wm_state, atom_atom,
 831             0, G_MAXLONG, FALSE, NULL, NULL, &length, (guchar**) &atoms)) {
 832 
 833         gint i = 0;
 834         bool is_hidden = false;
 835         bool is_above = false;
 836         while (i < length) {
 837             if (atom_net_wm_state_hidden == atoms[i]) {
 838                 is_hidden = true;
 839             } else if (atom_net_wm_state_above == atoms[i]) {
 840                 is_above = true;
 841             }

 842             i++;
 843         }
 844 
 845         g_free(atoms);
 846 
 847         if (is_iconified != is_hidden) {
 848             is_iconified = is_hidden;
 849 
 850             notify_state((is_hidden)
 851                     ? com_sun_glass_events_WindowEvent_MINIMIZE
 852                     : com_sun_glass_events_WindowEvent_RESTORE);
 853         }
 854         
 855         notify_on_top(is_above);
 856     }
 857 }
 858 
 859 void WindowContextTop::process_property_notify(GdkEventProperty* event) {
 860     if (event->atom == atom_net_wm_state && event->window == gdk_window) {
 861         process_net_wm_property();
 862     } else if (event->atom == get_net_frame_extents_atom() &&
 863             event->window == gdk_window) {
 864         int top, left, bottom, right;
 865         if (get_frame_extents_property(&top, &left, &bottom, &right)) {
 866             int oldX = geometry_get_window_x(&geometry);
 867             int oldY = geometry_get_window_y(&geometry);
 868             int oldWidth = geometry_get_content_width(&geometry);
 869             int oldHeight = geometry_get_content_height(&geometry);
 870 
 871             bool updateWindowConstraints = geometry.extents.top != top
 872                     || geometry.extents.left != left
 873                     || geometry.extents.bottom != bottom
 874                     || geometry.extents.right != right;
 875 


1329 
1330 void WindowContextTop::update_ontop_tree(bool on_top) {
1331     bool effective_on_top = on_top || this->on_top;
1332     gtk_window_set_keep_above(GTK_WINDOW(gtk_widget), effective_on_top ? TRUE : FALSE);
1333     for (std::set<WindowContextTop*>::iterator it = children.begin(); it != children.end(); ++it) {
1334         (*it)->update_ontop_tree(effective_on_top);
1335     }
1336 }
1337 
1338 bool WindowContextTop::on_top_inherited() {
1339     WindowContext* o = owner;
1340     while (o) {
1341         WindowContextTop* topO = dynamic_cast<WindowContextTop*>(o);
1342         if (!topO) break;
1343         if (topO->on_top) {
1344             return true;
1345         }
1346         o = topO->owner;
1347     }
1348     return false;
1349 }
1350 
1351 bool WindowContextTop::effective_on_top() {
1352     if (owner) {
1353         WindowContextTop* topO = dynamic_cast<WindowContextTop*>(owner);
1354         return (topO && topO->effective_on_top()) || on_top;
1355     }
1356     return on_top;
1357 }
1358 
1359 void WindowContextTop::notify_on_top(bool top) {
1360     // Do not report effective (i.e. native) values to the FX, only if the user sets it manually
1361     if (top != effective_on_top() && jwindow) {
1362         if (on_top_inherited() && !top) {
1363             // Disallow user's "on top" handling on windows that inherited the property
1364             gtk_window_set_keep_above(GTK_WINDOW(gtk_widget), TRUE);
1365         } else {
1366             on_top = top;
1367             update_ontop_tree(top);
1368             mainEnv->CallVoidMethod(jwindow,
1369                     jWindowNotifyLevelChanged,
1370                     top ? com_sun_glass_ui_Window_Level_FLOATING :  com_sun_glass_ui_Window_Level_NORMAL);
1371             CHECK_JNI_EXCEPTION(mainEnv);
1372         }
1373     }
1374 }
1375 
1376 void WindowContextTop::set_level(int level) {
1377     if (level == com_sun_glass_ui_Window_Level_NORMAL) {
1378         on_top = false;
1379     } else if (level == com_sun_glass_ui_Window_Level_FLOATING
1380             || level == com_sun_glass_ui_Window_Level_TOPMOST) {
1381         on_top = true;
1382     }
1383     // We need to emulate always on top behaviour on child windows
1384 
1385     if (!on_top_inherited()) {
1386         update_ontop_tree(on_top);
1387     }
1388 }
1389 
1390 void WindowContextTop::set_owner(WindowContext * owner_ctx) {
1391     owner = owner_ctx;
1392 }
1393