OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "views/widget/native_widget_gtk.h" | 5 #include "views/widget/native_widget_gtk.h" |
6 | 6 |
7 #include <gdk/gdk.h> | 7 #include <gdk/gdk.h> |
8 #include <gdk/gdkx.h> | 8 #include <gdk/gdkx.h> |
9 #include <X11/extensions/shape.h> | 9 #include <X11/extensions/shape.h> |
10 #include <X11/Xatom.h> | 10 #include <X11/Xatom.h> |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "views/controls/textfield/native_textfield_views.h" | 29 #include "views/controls/textfield/native_textfield_views.h" |
30 #include "views/focus/view_storage.h" | 30 #include "views/focus/view_storage.h" |
31 #include "views/ime/input_method_gtk.h" | 31 #include "views/ime/input_method_gtk.h" |
32 #include "views/screen.h" | 32 #include "views/screen.h" |
33 #include "views/views_delegate.h" | 33 #include "views/views_delegate.h" |
34 #include "views/widget/drop_target_gtk.h" | 34 #include "views/widget/drop_target_gtk.h" |
35 #include "views/widget/gtk_views_fixed.h" | 35 #include "views/widget/gtk_views_fixed.h" |
36 #include "views/widget/gtk_views_window.h" | 36 #include "views/widget/gtk_views_window.h" |
37 #include "views/widget/tooltip_manager_gtk.h" | 37 #include "views/widget/tooltip_manager_gtk.h" |
38 #include "views/widget/widget_delegate.h" | 38 #include "views/widget/widget_delegate.h" |
| 39 #include "views/window/hit_test.h" |
39 #include "views/window/native_window_gtk.h" | 40 #include "views/window/native_window_gtk.h" |
40 | 41 |
41 #if defined(TOUCH_UI) | 42 #if defined(TOUCH_UI) |
42 #if defined(HAVE_XINPUT2) | 43 #if defined(HAVE_XINPUT2) |
43 #include <gdk/gdkx.h> | 44 #include <gdk/gdkx.h> |
44 | 45 |
45 #include "ui/gfx/gtk_util.h" | 46 #include "ui/gfx/gtk_util.h" |
46 #include "views/touchui/touch_factory.h" | 47 #include "views/touchui/touch_factory.h" |
47 #endif | 48 #endif |
48 #endif | 49 #endif |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 | 174 |
174 void RemoveExposeHandlerIfExists(GtkWidget* widget) { | 175 void RemoveExposeHandlerIfExists(GtkWidget* widget) { |
175 gulong id = reinterpret_cast<gulong>(g_object_get_data(G_OBJECT(widget), | 176 gulong id = reinterpret_cast<gulong>(g_object_get_data(G_OBJECT(widget), |
176 kExposeHandlerIdKey)); | 177 kExposeHandlerIdKey)); |
177 if (id) { | 178 if (id) { |
178 g_signal_handler_disconnect(G_OBJECT(widget), id); | 179 g_signal_handler_disconnect(G_OBJECT(widget), id); |
179 g_object_set_data(G_OBJECT(widget), kExposeHandlerIdKey, 0); | 180 g_object_set_data(G_OBJECT(widget), kExposeHandlerIdKey, 0); |
180 } | 181 } |
181 } | 182 } |
182 | 183 |
| 184 // Converts a Windows-style hit test result code into a GDK window edge. |
| 185 GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) { |
| 186 switch (hittest_code) { |
| 187 case HTBOTTOM: |
| 188 return GDK_WINDOW_EDGE_SOUTH; |
| 189 case HTBOTTOMLEFT: |
| 190 return GDK_WINDOW_EDGE_SOUTH_WEST; |
| 191 case HTBOTTOMRIGHT: |
| 192 case HTGROWBOX: |
| 193 return GDK_WINDOW_EDGE_SOUTH_EAST; |
| 194 case HTLEFT: |
| 195 return GDK_WINDOW_EDGE_WEST; |
| 196 case HTRIGHT: |
| 197 return GDK_WINDOW_EDGE_EAST; |
| 198 case HTTOP: |
| 199 return GDK_WINDOW_EDGE_NORTH; |
| 200 case HTTOPLEFT: |
| 201 return GDK_WINDOW_EDGE_NORTH_WEST; |
| 202 case HTTOPRIGHT: |
| 203 return GDK_WINDOW_EDGE_NORTH_EAST; |
| 204 default: |
| 205 NOTREACHED(); |
| 206 break; |
| 207 } |
| 208 // Default to something defaultish. |
| 209 return HitTestCodeToGDKWindowEdge(HTGROWBOX); |
| 210 } |
| 211 |
| 212 // Converts a Windows-style hit test result code into a GDK cursor type. |
| 213 GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) { |
| 214 switch (hittest_code) { |
| 215 case HTBOTTOM: |
| 216 return GDK_BOTTOM_SIDE; |
| 217 case HTBOTTOMLEFT: |
| 218 return GDK_BOTTOM_LEFT_CORNER; |
| 219 case HTBOTTOMRIGHT: |
| 220 case HTGROWBOX: |
| 221 return GDK_BOTTOM_RIGHT_CORNER; |
| 222 case HTLEFT: |
| 223 return GDK_LEFT_SIDE; |
| 224 case HTRIGHT: |
| 225 return GDK_RIGHT_SIDE; |
| 226 case HTTOP: |
| 227 return GDK_TOP_SIDE; |
| 228 case HTTOPLEFT: |
| 229 return GDK_TOP_LEFT_CORNER; |
| 230 case HTTOPRIGHT: |
| 231 return GDK_TOP_RIGHT_CORNER; |
| 232 default: |
| 233 break; |
| 234 } |
| 235 // Default to something defaultish. |
| 236 return GDK_LEFT_PTR; |
| 237 } |
| 238 |
183 } // namespace | 239 } // namespace |
184 | 240 |
185 // During drag and drop GTK sends a drag-leave during a drop. This means we | 241 // During drag and drop GTK sends a drag-leave during a drop. This means we |
186 // have no way to tell the difference between a normal drag leave and a drop. | 242 // have no way to tell the difference between a normal drag leave and a drop. |
187 // To work around that we listen for DROP_START, then ignore the subsequent | 243 // To work around that we listen for DROP_START, then ignore the subsequent |
188 // drag-leave that GTK generates. | 244 // drag-leave that GTK generates. |
189 class NativeWidgetGtk::DropObserver : public MessageLoopForUI::Observer { | 245 class NativeWidgetGtk::DropObserver : public MessageLoopForUI::Observer { |
190 public: | 246 public: |
191 DropObserver() {} | 247 DropObserver() {} |
192 | 248 |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 g_signal_connect(widget_, "focus_out_event", | 739 g_signal_connect(widget_, "focus_out_event", |
684 G_CALLBACK(&OnFocusOutThunk), this); | 740 G_CALLBACK(&OnFocusOutThunk), this); |
685 g_signal_connect(widget_, "destroy", | 741 g_signal_connect(widget_, "destroy", |
686 G_CALLBACK(&OnDestroyThunk), this); | 742 G_CALLBACK(&OnDestroyThunk), this); |
687 g_signal_connect(widget_, "show", | 743 g_signal_connect(widget_, "show", |
688 G_CALLBACK(&OnShowThunk), this); | 744 G_CALLBACK(&OnShowThunk), this); |
689 g_signal_connect(widget_, "map", | 745 g_signal_connect(widget_, "map", |
690 G_CALLBACK(&OnMapThunk), this); | 746 G_CALLBACK(&OnMapThunk), this); |
691 g_signal_connect(widget_, "hide", | 747 g_signal_connect(widget_, "hide", |
692 G_CALLBACK(&OnHideThunk), this); | 748 G_CALLBACK(&OnHideThunk), this); |
| 749 g_signal_connect(G_OBJECT(widget_), "configure-event", |
| 750 G_CALLBACK(&OnConfigureEventThunk), this); |
693 | 751 |
694 // Views/FocusManager (re)sets the focus to the root window, | 752 // Views/FocusManager (re)sets the focus to the root window, |
695 // so we need to connect signal handlers to the gtk window. | 753 // so we need to connect signal handlers to the gtk window. |
696 // See views::Views::Focus and views::FocusManager::ClearNativeFocus | 754 // See views::Views::Focus and views::FocusManager::ClearNativeFocus |
697 // for more details. | 755 // for more details. |
698 g_signal_connect(widget_, "key_press_event", | 756 g_signal_connect(widget_, "key_press_event", |
699 G_CALLBACK(&OnEventKeyThunk), this); | 757 G_CALLBACK(&OnEventKeyThunk), this); |
700 g_signal_connect(widget_, "key_release_event", | 758 g_signal_connect(widget_, "key_release_event", |
701 G_CALLBACK(&OnEventKeyThunk), this); | 759 G_CALLBACK(&OnEventKeyThunk), this); |
702 | 760 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 | 953 |
896 void NativeWidgetGtk::SetAccessibleName(const std::wstring& name) { | 954 void NativeWidgetGtk::SetAccessibleName(const std::wstring& name) { |
897 } | 955 } |
898 | 956 |
899 void NativeWidgetGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { | 957 void NativeWidgetGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { |
900 } | 958 } |
901 | 959 |
902 void NativeWidgetGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { | 960 void NativeWidgetGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { |
903 } | 961 } |
904 | 962 |
| 963 void NativeWidgetGtk::BecomeModal() { |
| 964 gtk_window_set_modal(GetNativeWindow(), true); |
| 965 } |
| 966 |
905 gfx::Rect NativeWidgetGtk::GetWindowScreenBounds() const { | 967 gfx::Rect NativeWidgetGtk::GetWindowScreenBounds() const { |
906 // Client == Window bounds on Gtk. | 968 // Client == Window bounds on Gtk. |
907 return GetClientAreaScreenBounds(); | 969 return GetClientAreaScreenBounds(); |
908 } | 970 } |
909 | 971 |
910 gfx::Rect NativeWidgetGtk::GetClientAreaScreenBounds() const { | 972 gfx::Rect NativeWidgetGtk::GetClientAreaScreenBounds() const { |
911 // Due to timing we can get a request for bounds after Close(). | 973 // Due to timing we can get a request for bounds after Close(). |
912 // TODO(beng): Figure out if this is bogus. | 974 // TODO(beng): Figure out if this is bogus. |
913 if (!widget_) | 975 if (!widget_) |
914 return gfx::Rect(size_); | 976 return gfx::Rect(size_); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 GtkAllocation* allocation) { | 1250 GtkAllocation* allocation) { |
1189 // See comment next to size_ as to why we do this. Also note, it's tempting | 1251 // See comment next to size_ as to why we do this. Also note, it's tempting |
1190 // to put this in the static method so subclasses don't need to worry about | 1252 // to put this in the static method so subclasses don't need to worry about |
1191 // it, but if a subclasses needs to set a shape then they need to always | 1253 // it, but if a subclasses needs to set a shape then they need to always |
1192 // reset the shape in this method regardless of whether the size changed. | 1254 // reset the shape in this method regardless of whether the size changed. |
1193 gfx::Size new_size(allocation->width, allocation->height); | 1255 gfx::Size new_size(allocation->width, allocation->height); |
1194 if (new_size == size_) | 1256 if (new_size == size_) |
1195 return; | 1257 return; |
1196 size_ = new_size; | 1258 size_ = new_size; |
1197 delegate_->OnNativeWidgetSizeChanged(size_); | 1259 delegate_->OnNativeWidgetSizeChanged(size_); |
| 1260 |
| 1261 if (GetWidget()->non_client_view()) { |
| 1262 // The Window's NonClientView may provide a custom shape for the Window. |
| 1263 gfx::Path window_mask; |
| 1264 GetWidget()->non_client_view()->GetWindowMask(gfx::Size(allocation->width, |
| 1265 allocation->height), |
| 1266 &window_mask); |
| 1267 GdkRegion* mask_region = window_mask.CreateNativeRegion(); |
| 1268 gdk_window_shape_combine_region(GetNativeView()->window, mask_region, 0, 0); |
| 1269 if (mask_region) |
| 1270 gdk_region_destroy(mask_region); |
| 1271 |
| 1272 SaveWindowPosition(); |
| 1273 } |
1198 } | 1274 } |
1199 | 1275 |
1200 gboolean NativeWidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { | 1276 gboolean NativeWidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { |
1201 if (transparent_ && child_) { | 1277 if (transparent_ && child_) { |
1202 // Clear the background before drawing any view and native components. | 1278 // Clear the background before drawing any view and native components. |
1203 DrawTransparentBackground(widget, event); | 1279 DrawTransparentBackground(widget, event); |
1204 if (!CompositePainter::IsComposited(widget_) && | 1280 if (!CompositePainter::IsComposited(widget_) && |
1205 gdk_screen_is_composited(gdk_screen_get_default())) { | 1281 gdk_screen_is_composited(gdk_screen_get_default())) { |
1206 // Let the parent draw the content only after something is drawn on | 1282 // Let the parent draw the content only after something is drawn on |
1207 // the widget. | 1283 // the widget. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); | 1406 motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); |
1331 | 1407 |
1332 MouseEvent mouse_event(TransformEvent(&motion)); | 1408 MouseEvent mouse_event(TransformEvent(&motion)); |
1333 delegate_->OnMouseEvent(mouse_event); | 1409 delegate_->OnMouseEvent(mouse_event); |
1334 } | 1410 } |
1335 return false; | 1411 return false; |
1336 } | 1412 } |
1337 | 1413 |
1338 gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget, | 1414 gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget, |
1339 GdkEventCrossing* event) { | 1415 GdkEventCrossing* event) { |
| 1416 gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR)); |
| 1417 |
1340 GetWidget()->ResetLastMouseMoveFlag(); | 1418 GetWidget()->ResetLastMouseMoveFlag(); |
1341 | 1419 |
1342 if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { | 1420 if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { |
1343 MouseEvent mouse_event(TransformEvent(event)); | 1421 MouseEvent mouse_event(TransformEvent(event)); |
1344 delegate_->OnMouseEvent(mouse_event); | 1422 delegate_->OnMouseEvent(mouse_event); |
1345 } | 1423 } |
1346 return false; | 1424 return false; |
1347 } | 1425 } |
1348 | 1426 |
1349 gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget, | 1427 gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget, |
1350 GdkEventMotion* event) { | 1428 GdkEventMotion* event) { |
| 1429 if (GetWidget()->non_client_view()) { |
| 1430 GdkEventMotion transformed_event = *event; |
| 1431 TransformEvent(&transformed_event); |
| 1432 gfx::Point translated_location(transformed_event.x, transformed_event.y); |
| 1433 |
| 1434 // Update the cursor for the screen edge. |
| 1435 int hittest_code = |
| 1436 GetWindow()->non_client_view()->NonClientHitTest(translated_location); |
| 1437 if (hittest_code != HTCLIENT) { |
| 1438 GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code); |
| 1439 gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type)); |
| 1440 } |
| 1441 } |
| 1442 |
1351 MouseEvent mouse_event(TransformEvent(event)); | 1443 MouseEvent mouse_event(TransformEvent(event)); |
1352 delegate_->OnMouseEvent(mouse_event); | 1444 delegate_->OnMouseEvent(mouse_event); |
1353 return true; | 1445 return true; |
1354 } | 1446 } |
1355 | 1447 |
1356 gboolean NativeWidgetGtk::OnButtonPress(GtkWidget* widget, | 1448 gboolean NativeWidgetGtk::OnButtonPress(GtkWidget* widget, |
1357 GdkEventButton* event) { | 1449 GdkEventButton* event) { |
| 1450 if (GetWidget()->non_client_view()) { |
| 1451 GdkEventButton transformed_event = *event; |
| 1452 MouseEvent mouse_event(TransformEvent(&transformed_event)); |
| 1453 |
| 1454 int hittest_code = GetWidget()->non_client_view()->NonClientHitTest( |
| 1455 mouse_event.location()); |
| 1456 switch (hittest_code) { |
| 1457 case HTCAPTION: { |
| 1458 // Start dragging if the mouse event is a single click and *not* a right |
| 1459 // click. If it is a right click, then pass it through to |
| 1460 // NativeWidgetGtk::OnButtonPress so that View class can show |
| 1461 // ContextMenu upon a mouse release event. We only start drag on single |
| 1462 // clicks as we get a crash in Gtk on double/triple clicks. |
| 1463 if (event->type == GDK_BUTTON_PRESS && |
| 1464 !mouse_event.IsOnlyRightMouseButton()) { |
| 1465 gfx::Point screen_point(event->x, event->y); |
| 1466 View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point); |
| 1467 gtk_window_begin_move_drag(GetNativeWindow(), event->button, |
| 1468 screen_point.x(), screen_point.y(), |
| 1469 event->time); |
| 1470 return TRUE; |
| 1471 } |
| 1472 break; |
| 1473 } |
| 1474 case HTBOTTOM: |
| 1475 case HTBOTTOMLEFT: |
| 1476 case HTBOTTOMRIGHT: |
| 1477 case HTGROWBOX: |
| 1478 case HTLEFT: |
| 1479 case HTRIGHT: |
| 1480 case HTTOP: |
| 1481 case HTTOPLEFT: |
| 1482 case HTTOPRIGHT: { |
| 1483 gfx::Point screen_point(event->x, event->y); |
| 1484 View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point); |
| 1485 // TODO(beng): figure out how to get a good minimum size. |
| 1486 gtk_widget_set_size_request(GetNativeView(), 100, 100); |
| 1487 gtk_window_begin_resize_drag(GetNativeWindow(), |
| 1488 HitTestCodeToGDKWindowEdge(hittest_code), |
| 1489 event->button, screen_point.x(), |
| 1490 screen_point.y(), event->time); |
| 1491 return TRUE; |
| 1492 } |
| 1493 default: |
| 1494 // Everything else falls into standard client event handling... |
| 1495 break; |
| 1496 } |
| 1497 } |
| 1498 |
1358 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { | 1499 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { |
1359 // The sequence for double clicks is press, release, press, 2press, release. | 1500 // The sequence for double clicks is press, release, press, 2press, release. |
1360 // This means that at the time we get the second 'press' we don't know | 1501 // This means that at the time we get the second 'press' we don't know |
1361 // whether it corresponds to a double click or not. For now we're completely | 1502 // whether it corresponds to a double click or not. For now we're completely |
1362 // ignoring the 2press/3press events as they are duplicate. To make this | 1503 // ignoring the 2press/3press events as they are duplicate. To make this |
1363 // work right we need to write our own code that detects if the press is a | 1504 // work right we need to write our own code that detects if the press is a |
1364 // double/triple. For now we're completely punting, which means we always | 1505 // double/triple. For now we're completely punting, which means we always |
1365 // get single clicks. | 1506 // get single clicks. |
1366 // TODO: fix this. | 1507 // TODO: fix this. |
1367 return true; | 1508 return true; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 // as we're removing gtk and migrating to new compositor. | 1630 // as we're removing gtk and migrating to new compositor. |
1490 gdk_window_process_all_updates(); | 1631 gdk_window_process_all_updates(); |
1491 #endif | 1632 #endif |
1492 } | 1633 } |
1493 | 1634 |
1494 void NativeWidgetGtk::OnHide(GtkWidget* widget) { | 1635 void NativeWidgetGtk::OnHide(GtkWidget* widget) { |
1495 } | 1636 } |
1496 | 1637 |
1497 gboolean NativeWidgetGtk::OnWindowStateEvent(GtkWidget* widget, | 1638 gboolean NativeWidgetGtk::OnWindowStateEvent(GtkWidget* widget, |
1498 GdkEventWindowState* event) { | 1639 GdkEventWindowState* event) { |
| 1640 if (GetWidget()->non_client_view() && |
| 1641 !(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)) { |
| 1642 SaveWindowPosition(); |
| 1643 } |
1499 window_state_ = event->new_window_state; | 1644 window_state_ = event->new_window_state; |
1500 return FALSE; | 1645 return FALSE; |
1501 } | 1646 } |
1502 | 1647 |
| 1648 gboolean NativeWidgetGtk::OnConfigureEvent(GtkWidget* widget) { |
| 1649 SaveWindowPosition(); |
| 1650 return FALSE; |
| 1651 } |
| 1652 |
1503 void NativeWidgetGtk::HandleXGrabBroke() { | 1653 void NativeWidgetGtk::HandleXGrabBroke() { |
1504 } | 1654 } |
1505 | 1655 |
1506 void NativeWidgetGtk::HandleGtkGrabBroke() { | 1656 void NativeWidgetGtk::HandleGtkGrabBroke() { |
1507 delegate_->OnMouseCaptureLost(); | 1657 delegate_->OnMouseCaptureLost(); |
1508 } | 1658 } |
1509 | 1659 |
1510 //////////////////////////////////////////////////////////////////////////////// | 1660 //////////////////////////////////////////////////////////////////////////////// |
1511 // NativeWidgetGtk, private: | 1661 // NativeWidgetGtk, private: |
1512 | 1662 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 | 1940 |
1791 void NativeWidgetGtk::DrawTransparentBackground(GtkWidget* widget, | 1941 void NativeWidgetGtk::DrawTransparentBackground(GtkWidget* widget, |
1792 GdkEventExpose* event) { | 1942 GdkEventExpose* event) { |
1793 cairo_t* cr = gdk_cairo_create(widget->window); | 1943 cairo_t* cr = gdk_cairo_create(widget->window); |
1794 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); | 1944 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); |
1795 gdk_cairo_region(cr, event->region); | 1945 gdk_cairo_region(cr, event->region); |
1796 cairo_fill(cr); | 1946 cairo_fill(cr); |
1797 cairo_destroy(cr); | 1947 cairo_destroy(cr); |
1798 } | 1948 } |
1799 | 1949 |
| 1950 void NativeWindowGtk::SaveWindowPosition() { |
| 1951 // The delegate may have gone away on us. |
| 1952 if (!GetWidget()->widget_delegate()) |
| 1953 return; |
| 1954 |
| 1955 bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED; |
| 1956 GetWidget()->widget_delegate()->SaveWindowPlacement( |
| 1957 GetWidget()->GetWindowScreenBounds(), |
| 1958 maximized); |
| 1959 } |
| 1960 |
1800 //////////////////////////////////////////////////////////////////////////////// | 1961 //////////////////////////////////////////////////////////////////////////////// |
1801 // Widget, public: | 1962 // Widget, public: |
1802 | 1963 |
1803 // static | 1964 // static |
1804 void Widget::NotifyLocaleChanged() { | 1965 void Widget::NotifyLocaleChanged() { |
1805 GList *window_list = gtk_window_list_toplevels(); | 1966 GList *window_list = gtk_window_list_toplevels(); |
1806 for (GList* element = window_list; element; element = g_list_next(element)) { | 1967 for (GList* element = window_list; element; element = g_list_next(element)) { |
1807 NativeWidget* native_widget = | 1968 NativeWidget* native_widget = |
1808 NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data)); | 1969 NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data)); |
1809 if (native_widget) | 1970 if (native_widget) |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1945 | 2106 |
1946 // And now, notify them that they have a brand new parent. | 2107 // And now, notify them that they have a brand new parent. |
1947 for (NativeWidgets::iterator it = widgets.begin(); | 2108 for (NativeWidgets::iterator it = widgets.begin(); |
1948 it != widgets.end(); ++it) { | 2109 it != widgets.end(); ++it) { |
1949 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, | 2110 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, |
1950 new_parent); | 2111 new_parent); |
1951 } | 2112 } |
1952 } | 2113 } |
1953 | 2114 |
1954 } // namespace views | 2115 } // namespace views |
OLD | NEW |