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> |
11 #include <X11/Xlib.h> | 11 #include <X11/Xlib.h> |
12 | 12 |
13 #include <set> | 13 #include <set> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/auto_reset.h" | 16 #include "base/auto_reset.h" |
17 #include "base/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
18 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
19 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
20 #include "ui/base/dragdrop/drag_drop_types.h" | 20 #include "ui/base/dragdrop/drag_drop_types.h" |
21 #include "ui/base/dragdrop/os_exchange_data.h" | 21 #include "ui/base/dragdrop/os_exchange_data.h" |
22 #include "ui/base/dragdrop/os_exchange_data_provider_gtk.h" | 22 #include "ui/base/dragdrop/os_exchange_data_provider_gtk.h" |
23 #include "ui/base/gtk/g_object_destructor_filo.h" | 23 #include "ui/base/gtk/g_object_destructor_filo.h" |
24 #include "ui/base/gtk/gtk_windowing.h" | 24 #include "ui/base/gtk/gtk_windowing.h" |
25 #include "ui/base/gtk/scoped_handle_gtk.h" | 25 #include "ui/base/gtk/scoped_handle_gtk.h" |
26 #include "ui/base/x/x11_util.h" | 26 #include "ui/base/x/x11_util.h" |
27 #include "ui/gfx/canvas_skia_paint.h" | 27 #include "ui/gfx/canvas_skia_paint.h" |
| 28 #include "ui/gfx/gtk_util.h" |
28 #include "ui/gfx/path.h" | 29 #include "ui/gfx/path.h" |
29 #include "views/controls/textfield/native_textfield_views.h" | 30 #include "views/controls/textfield/native_textfield_views.h" |
30 #include "views/focus/view_storage.h" | 31 #include "views/focus/view_storage.h" |
31 #include "views/ime/input_method_gtk.h" | 32 #include "views/ime/input_method_gtk.h" |
32 #include "views/screen.h" | 33 #include "views/screen.h" |
33 #include "views/views_delegate.h" | 34 #include "views/views_delegate.h" |
34 #include "views/widget/drop_target_gtk.h" | 35 #include "views/widget/drop_target_gtk.h" |
35 #include "views/widget/gtk_views_fixed.h" | 36 #include "views/widget/gtk_views_fixed.h" |
36 #include "views/widget/gtk_views_window.h" | 37 #include "views/widget/gtk_views_window.h" |
37 #include "views/widget/tooltip_manager_gtk.h" | 38 #include "views/widget/tooltip_manager_gtk.h" |
38 #include "views/widget/widget_delegate.h" | 39 #include "views/widget/widget_delegate.h" |
| 40 #include "views/window/hit_test.h" |
39 #include "views/window/native_window_gtk.h" | 41 #include "views/window/native_window_gtk.h" |
40 | 42 |
41 #if defined(TOUCH_UI) | 43 #if defined(TOUCH_UI) |
42 #if defined(HAVE_XINPUT2) | 44 #if defined(HAVE_XINPUT2) |
43 #include <gdk/gdkx.h> | 45 #include <gdk/gdkx.h> |
44 | 46 |
45 #include "ui/gfx/gtk_util.h" | 47 #include "ui/gfx/gtk_util.h" |
46 #include "views/touchui/touch_factory.h" | 48 #include "views/touchui/touch_factory.h" |
47 #endif | 49 #endif |
48 #endif | 50 #endif |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 case Widget::InitParams::TYPE_WINDOW: | 187 case Widget::InitParams::TYPE_WINDOW: |
186 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: | 188 case Widget::InitParams::TYPE_WINDOW_FRAMELESS: |
187 return GTK_WINDOW_TOPLEVEL; | 189 return GTK_WINDOW_TOPLEVEL; |
188 default: | 190 default: |
189 return GTK_WINDOW_POPUP; | 191 return GTK_WINDOW_POPUP; |
190 } | 192 } |
191 NOTREACHED(); | 193 NOTREACHED(); |
192 return GTK_WINDOW_TOPLEVEL; | 194 return GTK_WINDOW_TOPLEVEL; |
193 } | 195 } |
194 | 196 |
| 197 // Converts a Windows-style hit test result code into a GDK window edge. |
| 198 GdkWindowEdge HitTestCodeToGDKWindowEdge(int hittest_code) { |
| 199 switch (hittest_code) { |
| 200 case HTBOTTOM: |
| 201 return GDK_WINDOW_EDGE_SOUTH; |
| 202 case HTBOTTOMLEFT: |
| 203 return GDK_WINDOW_EDGE_SOUTH_WEST; |
| 204 case HTBOTTOMRIGHT: |
| 205 case HTGROWBOX: |
| 206 return GDK_WINDOW_EDGE_SOUTH_EAST; |
| 207 case HTLEFT: |
| 208 return GDK_WINDOW_EDGE_WEST; |
| 209 case HTRIGHT: |
| 210 return GDK_WINDOW_EDGE_EAST; |
| 211 case HTTOP: |
| 212 return GDK_WINDOW_EDGE_NORTH; |
| 213 case HTTOPLEFT: |
| 214 return GDK_WINDOW_EDGE_NORTH_WEST; |
| 215 case HTTOPRIGHT: |
| 216 return GDK_WINDOW_EDGE_NORTH_EAST; |
| 217 default: |
| 218 NOTREACHED(); |
| 219 break; |
| 220 } |
| 221 // Default to something defaultish. |
| 222 return HitTestCodeToGDKWindowEdge(HTGROWBOX); |
| 223 } |
| 224 |
| 225 // Converts a Windows-style hit test result code into a GDK cursor type. |
| 226 GdkCursorType HitTestCodeToGdkCursorType(int hittest_code) { |
| 227 switch (hittest_code) { |
| 228 case HTBOTTOM: |
| 229 return GDK_BOTTOM_SIDE; |
| 230 case HTBOTTOMLEFT: |
| 231 return GDK_BOTTOM_LEFT_CORNER; |
| 232 case HTBOTTOMRIGHT: |
| 233 case HTGROWBOX: |
| 234 return GDK_BOTTOM_RIGHT_CORNER; |
| 235 case HTLEFT: |
| 236 return GDK_LEFT_SIDE; |
| 237 case HTRIGHT: |
| 238 return GDK_RIGHT_SIDE; |
| 239 case HTTOP: |
| 240 return GDK_TOP_SIDE; |
| 241 case HTTOPLEFT: |
| 242 return GDK_TOP_LEFT_CORNER; |
| 243 case HTTOPRIGHT: |
| 244 return GDK_TOP_RIGHT_CORNER; |
| 245 default: |
| 246 break; |
| 247 } |
| 248 // Default to something defaultish. |
| 249 return GDK_LEFT_PTR; |
| 250 } |
| 251 |
195 } // namespace | 252 } // namespace |
196 | 253 |
197 // During drag and drop GTK sends a drag-leave during a drop. This means we | 254 // During drag and drop GTK sends a drag-leave during a drop. This means we |
198 // have no way to tell the difference between a normal drag leave and a drop. | 255 // have no way to tell the difference between a normal drag leave and a drop. |
199 // To work around that we listen for DROP_START, then ignore the subsequent | 256 // To work around that we listen for DROP_START, then ignore the subsequent |
200 // drag-leave that GTK generates. | 257 // drag-leave that GTK generates. |
201 class NativeWidgetGtk::DropObserver : public MessageLoopForUI::Observer { | 258 class NativeWidgetGtk::DropObserver : public MessageLoopForUI::Observer { |
202 public: | 259 public: |
203 DropObserver() {} | 260 DropObserver() {} |
204 | 261 |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 g_signal_connect(widget_, "focus_out_event", | 752 g_signal_connect(widget_, "focus_out_event", |
696 G_CALLBACK(&OnFocusOutThunk), this); | 753 G_CALLBACK(&OnFocusOutThunk), this); |
697 g_signal_connect(widget_, "destroy", | 754 g_signal_connect(widget_, "destroy", |
698 G_CALLBACK(&OnDestroyThunk), this); | 755 G_CALLBACK(&OnDestroyThunk), this); |
699 g_signal_connect(widget_, "show", | 756 g_signal_connect(widget_, "show", |
700 G_CALLBACK(&OnShowThunk), this); | 757 G_CALLBACK(&OnShowThunk), this); |
701 g_signal_connect(widget_, "map", | 758 g_signal_connect(widget_, "map", |
702 G_CALLBACK(&OnMapThunk), this); | 759 G_CALLBACK(&OnMapThunk), this); |
703 g_signal_connect(widget_, "hide", | 760 g_signal_connect(widget_, "hide", |
704 G_CALLBACK(&OnHideThunk), this); | 761 G_CALLBACK(&OnHideThunk), this); |
| 762 g_signal_connect(widget_, "configure-event", |
| 763 G_CALLBACK(&OnConfigureEventThunk), this); |
705 | 764 |
706 // Views/FocusManager (re)sets the focus to the root window, | 765 // Views/FocusManager (re)sets the focus to the root window, |
707 // so we need to connect signal handlers to the gtk window. | 766 // so we need to connect signal handlers to the gtk window. |
708 // See views::Views::Focus and views::FocusManager::ClearNativeFocus | 767 // See views::Views::Focus and views::FocusManager::ClearNativeFocus |
709 // for more details. | 768 // for more details. |
710 g_signal_connect(widget_, "key_press_event", | 769 g_signal_connect(widget_, "key_press_event", |
711 G_CALLBACK(&OnEventKeyThunk), this); | 770 G_CALLBACK(&OnEventKeyThunk), this); |
712 g_signal_connect(widget_, "key_release_event", | 771 g_signal_connect(widget_, "key_release_event", |
713 G_CALLBACK(&OnEventKeyThunk), this); | 772 G_CALLBACK(&OnEventKeyThunk), this); |
714 | 773 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 | 966 |
908 void NativeWidgetGtk::SetAccessibleName(const std::wstring& name) { | 967 void NativeWidgetGtk::SetAccessibleName(const std::wstring& name) { |
909 } | 968 } |
910 | 969 |
911 void NativeWidgetGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { | 970 void NativeWidgetGtk::SetAccessibleRole(ui::AccessibilityTypes::Role role) { |
912 } | 971 } |
913 | 972 |
914 void NativeWidgetGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { | 973 void NativeWidgetGtk::SetAccessibleState(ui::AccessibilityTypes::State state) { |
915 } | 974 } |
916 | 975 |
| 976 void NativeWidgetGtk::BecomeModal() { |
| 977 gtk_window_set_modal(GetNativeWindow(), true); |
| 978 } |
| 979 |
917 gfx::Rect NativeWidgetGtk::GetWindowScreenBounds() const { | 980 gfx::Rect NativeWidgetGtk::GetWindowScreenBounds() const { |
918 // Client == Window bounds on Gtk. | 981 // Client == Window bounds on Gtk. |
919 return GetClientAreaScreenBounds(); | 982 return GetClientAreaScreenBounds(); |
920 } | 983 } |
921 | 984 |
922 gfx::Rect NativeWidgetGtk::GetClientAreaScreenBounds() const { | 985 gfx::Rect NativeWidgetGtk::GetClientAreaScreenBounds() const { |
923 // Due to timing we can get a request for bounds after Close(). | 986 // Due to timing we can get a request for bounds after Close(). |
924 // TODO(beng): Figure out if this is bogus. | 987 // TODO(beng): Figure out if this is bogus. |
925 if (!widget_) | 988 if (!widget_) |
926 return gfx::Rect(size_); | 989 return gfx::Rect(size_); |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 GtkAllocation* allocation) { | 1263 GtkAllocation* allocation) { |
1201 // See comment next to size_ as to why we do this. Also note, it's tempting | 1264 // See comment next to size_ as to why we do this. Also note, it's tempting |
1202 // to put this in the static method so subclasses don't need to worry about | 1265 // to put this in the static method so subclasses don't need to worry about |
1203 // it, but if a subclasses needs to set a shape then they need to always | 1266 // it, but if a subclasses needs to set a shape then they need to always |
1204 // reset the shape in this method regardless of whether the size changed. | 1267 // reset the shape in this method regardless of whether the size changed. |
1205 gfx::Size new_size(allocation->width, allocation->height); | 1268 gfx::Size new_size(allocation->width, allocation->height); |
1206 if (new_size == size_) | 1269 if (new_size == size_) |
1207 return; | 1270 return; |
1208 size_ = new_size; | 1271 size_ = new_size; |
1209 delegate_->OnNativeWidgetSizeChanged(size_); | 1272 delegate_->OnNativeWidgetSizeChanged(size_); |
| 1273 |
| 1274 if (GetWidget()->non_client_view()) { |
| 1275 // The Window's NonClientView may provide a custom shape for the Window. |
| 1276 gfx::Path window_mask; |
| 1277 GetWidget()->non_client_view()->GetWindowMask(gfx::Size(allocation->width, |
| 1278 allocation->height), |
| 1279 &window_mask); |
| 1280 GdkRegion* mask_region = window_mask.CreateNativeRegion(); |
| 1281 gdk_window_shape_combine_region(GetNativeView()->window, mask_region, 0, 0); |
| 1282 if (mask_region) |
| 1283 gdk_region_destroy(mask_region); |
| 1284 |
| 1285 SaveWindowPosition(); |
| 1286 } |
1210 } | 1287 } |
1211 | 1288 |
1212 gboolean NativeWidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { | 1289 gboolean NativeWidgetGtk::OnPaint(GtkWidget* widget, GdkEventExpose* event) { |
1213 if (transparent_ && child_) { | 1290 if (transparent_ && child_) { |
1214 // Clear the background before drawing any view and native components. | 1291 // Clear the background before drawing any view and native components. |
1215 DrawTransparentBackground(widget, event); | 1292 DrawTransparentBackground(widget, event); |
1216 if (!CompositePainter::IsComposited(widget_) && | 1293 if (!CompositePainter::IsComposited(widget_) && |
1217 gdk_screen_is_composited(gdk_screen_get_default())) { | 1294 gdk_screen_is_composited(gdk_screen_get_default())) { |
1218 // Let the parent draw the content only after something is drawn on | 1295 // Let the parent draw the content only after something is drawn on |
1219 // the widget. | 1296 // the widget. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); | 1419 motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); |
1343 | 1420 |
1344 MouseEvent mouse_event(TransformEvent(&motion)); | 1421 MouseEvent mouse_event(TransformEvent(&motion)); |
1345 delegate_->OnMouseEvent(mouse_event); | 1422 delegate_->OnMouseEvent(mouse_event); |
1346 } | 1423 } |
1347 return false; | 1424 return false; |
1348 } | 1425 } |
1349 | 1426 |
1350 gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget, | 1427 gboolean NativeWidgetGtk::OnLeaveNotify(GtkWidget* widget, |
1351 GdkEventCrossing* event) { | 1428 GdkEventCrossing* event) { |
| 1429 gdk_window_set_cursor(widget->window, gfx::GetCursor(GDK_LEFT_PTR)); |
| 1430 |
1352 GetWidget()->ResetLastMouseMoveFlag(); | 1431 GetWidget()->ResetLastMouseMoveFlag(); |
1353 | 1432 |
1354 if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { | 1433 if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { |
1355 MouseEvent mouse_event(TransformEvent(event)); | 1434 MouseEvent mouse_event(TransformEvent(event)); |
1356 delegate_->OnMouseEvent(mouse_event); | 1435 delegate_->OnMouseEvent(mouse_event); |
1357 } | 1436 } |
1358 return false; | 1437 return false; |
1359 } | 1438 } |
1360 | 1439 |
1361 gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget, | 1440 gboolean NativeWidgetGtk::OnMotionNotify(GtkWidget* widget, |
1362 GdkEventMotion* event) { | 1441 GdkEventMotion* event) { |
| 1442 if (GetWidget()->non_client_view()) { |
| 1443 GdkEventMotion transformed_event = *event; |
| 1444 TransformEvent(&transformed_event); |
| 1445 gfx::Point translated_location(transformed_event.x, transformed_event.y); |
| 1446 |
| 1447 // Update the cursor for the screen edge. |
| 1448 int hittest_code = |
| 1449 GetWidget()->non_client_view()->NonClientHitTest(translated_location); |
| 1450 if (hittest_code != HTCLIENT) { |
| 1451 GdkCursorType cursor_type = HitTestCodeToGdkCursorType(hittest_code); |
| 1452 gdk_window_set_cursor(widget->window, gfx::GetCursor(cursor_type)); |
| 1453 } |
| 1454 } |
| 1455 |
1363 MouseEvent mouse_event(TransformEvent(event)); | 1456 MouseEvent mouse_event(TransformEvent(event)); |
1364 delegate_->OnMouseEvent(mouse_event); | 1457 delegate_->OnMouseEvent(mouse_event); |
1365 return true; | 1458 return true; |
1366 } | 1459 } |
1367 | 1460 |
1368 gboolean NativeWidgetGtk::OnButtonPress(GtkWidget* widget, | 1461 gboolean NativeWidgetGtk::OnButtonPress(GtkWidget* widget, |
1369 GdkEventButton* event) { | 1462 GdkEventButton* event) { |
| 1463 if (GetWidget()->non_client_view()) { |
| 1464 GdkEventButton transformed_event = *event; |
| 1465 MouseEvent mouse_event(TransformEvent(&transformed_event)); |
| 1466 |
| 1467 int hittest_code = GetWidget()->non_client_view()->NonClientHitTest( |
| 1468 mouse_event.location()); |
| 1469 switch (hittest_code) { |
| 1470 case HTCAPTION: { |
| 1471 // Start dragging if the mouse event is a single click and *not* a right |
| 1472 // click. If it is a right click, then pass it through to |
| 1473 // NativeWidgetGtk::OnButtonPress so that View class can show |
| 1474 // ContextMenu upon a mouse release event. We only start drag on single |
| 1475 // clicks as we get a crash in Gtk on double/triple clicks. |
| 1476 if (event->type == GDK_BUTTON_PRESS && |
| 1477 !mouse_event.IsOnlyRightMouseButton()) { |
| 1478 gfx::Point screen_point(event->x, event->y); |
| 1479 View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point); |
| 1480 gtk_window_begin_move_drag(GetNativeWindow(), event->button, |
| 1481 screen_point.x(), screen_point.y(), |
| 1482 event->time); |
| 1483 return TRUE; |
| 1484 } |
| 1485 break; |
| 1486 } |
| 1487 case HTBOTTOM: |
| 1488 case HTBOTTOMLEFT: |
| 1489 case HTBOTTOMRIGHT: |
| 1490 case HTGROWBOX: |
| 1491 case HTLEFT: |
| 1492 case HTRIGHT: |
| 1493 case HTTOP: |
| 1494 case HTTOPLEFT: |
| 1495 case HTTOPRIGHT: { |
| 1496 gfx::Point screen_point(event->x, event->y); |
| 1497 View::ConvertPointToScreen(GetWidget()->GetRootView(), &screen_point); |
| 1498 // TODO(beng): figure out how to get a good minimum size. |
| 1499 gtk_widget_set_size_request(GetNativeView(), 100, 100); |
| 1500 gtk_window_begin_resize_drag(GetNativeWindow(), |
| 1501 HitTestCodeToGDKWindowEdge(hittest_code), |
| 1502 event->button, screen_point.x(), |
| 1503 screen_point.y(), event->time); |
| 1504 return TRUE; |
| 1505 } |
| 1506 default: |
| 1507 // Everything else falls into standard client event handling... |
| 1508 break; |
| 1509 } |
| 1510 } |
| 1511 |
1370 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { | 1512 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { |
1371 // The sequence for double clicks is press, release, press, 2press, release. | 1513 // The sequence for double clicks is press, release, press, 2press, release. |
1372 // This means that at the time we get the second 'press' we don't know | 1514 // This means that at the time we get the second 'press' we don't know |
1373 // whether it corresponds to a double click or not. For now we're completely | 1515 // whether it corresponds to a double click or not. For now we're completely |
1374 // ignoring the 2press/3press events as they are duplicate. To make this | 1516 // ignoring the 2press/3press events as they are duplicate. To make this |
1375 // work right we need to write our own code that detects if the press is a | 1517 // work right we need to write our own code that detects if the press is a |
1376 // double/triple. For now we're completely punting, which means we always | 1518 // double/triple. For now we're completely punting, which means we always |
1377 // get single clicks. | 1519 // get single clicks. |
1378 // TODO: fix this. | 1520 // TODO: fix this. |
1379 return true; | 1521 return true; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 // as we're removing gtk and migrating to new compositor. | 1643 // as we're removing gtk and migrating to new compositor. |
1502 gdk_window_process_all_updates(); | 1644 gdk_window_process_all_updates(); |
1503 #endif | 1645 #endif |
1504 } | 1646 } |
1505 | 1647 |
1506 void NativeWidgetGtk::OnHide(GtkWidget* widget) { | 1648 void NativeWidgetGtk::OnHide(GtkWidget* widget) { |
1507 } | 1649 } |
1508 | 1650 |
1509 gboolean NativeWidgetGtk::OnWindowStateEvent(GtkWidget* widget, | 1651 gboolean NativeWidgetGtk::OnWindowStateEvent(GtkWidget* widget, |
1510 GdkEventWindowState* event) { | 1652 GdkEventWindowState* event) { |
| 1653 if (GetWidget()->non_client_view() && |
| 1654 !(event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)) { |
| 1655 SaveWindowPosition(); |
| 1656 } |
1511 window_state_ = event->new_window_state; | 1657 window_state_ = event->new_window_state; |
1512 return FALSE; | 1658 return FALSE; |
1513 } | 1659 } |
1514 | 1660 |
| 1661 gboolean NativeWidgetGtk::OnConfigureEvent(GtkWidget* widget, |
| 1662 GdkEventConfigure* event) { |
| 1663 SaveWindowPosition(); |
| 1664 return FALSE; |
| 1665 } |
| 1666 |
1515 void NativeWidgetGtk::HandleXGrabBroke() { | 1667 void NativeWidgetGtk::HandleXGrabBroke() { |
1516 } | 1668 } |
1517 | 1669 |
1518 void NativeWidgetGtk::HandleGtkGrabBroke() { | 1670 void NativeWidgetGtk::HandleGtkGrabBroke() { |
1519 delegate_->OnMouseCaptureLost(); | 1671 delegate_->OnMouseCaptureLost(); |
1520 } | 1672 } |
1521 | 1673 |
1522 //////////////////////////////////////////////////////////////////////////////// | 1674 //////////////////////////////////////////////////////////////////////////////// |
1523 // NativeWidgetGtk, private: | 1675 // NativeWidgetGtk, private: |
1524 | 1676 |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1800 | 1952 |
1801 void NativeWidgetGtk::DrawTransparentBackground(GtkWidget* widget, | 1953 void NativeWidgetGtk::DrawTransparentBackground(GtkWidget* widget, |
1802 GdkEventExpose* event) { | 1954 GdkEventExpose* event) { |
1803 cairo_t* cr = gdk_cairo_create(widget->window); | 1955 cairo_t* cr = gdk_cairo_create(widget->window); |
1804 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); | 1956 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); |
1805 gdk_cairo_region(cr, event->region); | 1957 gdk_cairo_region(cr, event->region); |
1806 cairo_fill(cr); | 1958 cairo_fill(cr); |
1807 cairo_destroy(cr); | 1959 cairo_destroy(cr); |
1808 } | 1960 } |
1809 | 1961 |
| 1962 void NativeWidgetGtk::SaveWindowPosition() { |
| 1963 // The delegate may have gone away on us. |
| 1964 if (!GetWidget()->widget_delegate()) |
| 1965 return; |
| 1966 |
| 1967 bool maximized = window_state_ & GDK_WINDOW_STATE_MAXIMIZED; |
| 1968 GetWidget()->widget_delegate()->SaveWindowPlacement( |
| 1969 GetWidget()->GetWindowScreenBounds(), |
| 1970 maximized); |
| 1971 } |
| 1972 |
1810 //////////////////////////////////////////////////////////////////////////////// | 1973 //////////////////////////////////////////////////////////////////////////////// |
1811 // Widget, public: | 1974 // Widget, public: |
1812 | 1975 |
1813 // static | 1976 // static |
1814 void Widget::NotifyLocaleChanged() { | 1977 void Widget::NotifyLocaleChanged() { |
1815 GList *window_list = gtk_window_list_toplevels(); | 1978 GList *window_list = gtk_window_list_toplevels(); |
1816 for (GList* element = window_list; element; element = g_list_next(element)) { | 1979 for (GList* element = window_list; element; element = g_list_next(element)) { |
1817 NativeWidget* native_widget = | 1980 NativeWidget* native_widget = |
1818 NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data)); | 1981 NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data)); |
1819 if (native_widget) | 1982 if (native_widget) |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 | 2118 |
1956 // And now, notify them that they have a brand new parent. | 2119 // And now, notify them that they have a brand new parent. |
1957 for (NativeWidgets::iterator it = widgets.begin(); | 2120 for (NativeWidgets::iterator it = widgets.begin(); |
1958 it != widgets.end(); ++it) { | 2121 it != widgets.end(); ++it) { |
1959 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, | 2122 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, |
1960 new_parent); | 2123 new_parent); |
1961 } | 2124 } |
1962 } | 2125 } |
1963 | 2126 |
1964 } // namespace views | 2127 } // namespace views |
OLD | NEW |