| 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/widget_gtk.h" | 5 #include "views/widget/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 | 10 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 | 258 |
| 259 //////////////////////////////////////////////////////////////////////////////// | 259 //////////////////////////////////////////////////////////////////////////////// |
| 260 // WidgetGtk, public: | 260 // WidgetGtk, public: |
| 261 | 261 |
| 262 WidgetGtk::WidgetGtk(Type type) | 262 WidgetGtk::WidgetGtk(Type type) |
| 263 : is_window_(false), | 263 : is_window_(false), |
| 264 ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), | 264 ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), |
| 265 type_(type), | 265 type_(type), |
| 266 widget_(NULL), | 266 widget_(NULL), |
| 267 window_contents_(NULL), | 267 window_contents_(NULL), |
| 268 is_mouse_down_(false), | |
| 269 last_mouse_event_was_move_(false), | |
| 270 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), | 268 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
| 271 delete_on_destroy_(true), | 269 delete_on_destroy_(true), |
| 272 transparent_(false), | 270 transparent_(false), |
| 273 ignore_events_(false), | 271 ignore_events_(false), |
| 274 ignore_drag_leave_(false), | 272 ignore_drag_leave_(false), |
| 275 opacity_(255), | 273 opacity_(255), |
| 276 drag_data_(NULL), | 274 drag_data_(NULL), |
| 277 is_active_(false), | 275 is_active_(false), |
| 278 transient_to_parent_(false), | 276 transient_to_parent_(false), |
| 279 got_initial_focus_in_(false), | 277 got_initial_focus_in_(false), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 304 set_delete_on_destroy(params.delete_on_destroy); | 302 set_delete_on_destroy(params.delete_on_destroy); |
| 305 | 303 |
| 306 if (params.transparent) | 304 if (params.transparent) |
| 307 MakeTransparent(); | 305 MakeTransparent(); |
| 308 if (!params.accept_events) | 306 if (!params.accept_events) |
| 309 MakeIgnoreEvents(); | 307 MakeIgnoreEvents(); |
| 310 | 308 |
| 311 if (params.type == CreateParams::TYPE_MENU) { | 309 if (params.type == CreateParams::TYPE_MENU) { |
| 312 GdkEvent* event = gtk_get_current_event(); | 310 GdkEvent* event = gtk_get_current_event(); |
| 313 if (event) { | 311 if (event) { |
| 314 is_mouse_down_ = event->type == GDK_BUTTON_PRESS || | 312 is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS || |
| 315 event->type == GDK_2BUTTON_PRESS || | 313 event->type == GDK_2BUTTON_PRESS || |
| 316 event->type == GDK_3BUTTON_PRESS; | 314 event->type == GDK_3BUTTON_PRESS; |
| 317 gdk_event_free(event); | 315 gdk_event_free(event); |
| 318 } | 316 } |
| 319 } | 317 } |
| 320 } | 318 } |
| 321 | 319 |
| 322 GtkWindow* WidgetGtk::GetTransientParent() const { | 320 GtkWindow* WidgetGtk::GetTransientParent() const { |
| 323 return (type_ != TYPE_CHILD && widget_) ? | 321 return (type_ != TYPE_CHILD && widget_) ? |
| 324 gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL; | 322 gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL; |
| 325 } | 323 } |
| 326 | 324 |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 // Trigger VKEY_MENU when only this key is pressed and released, and both | 689 // Trigger VKEY_MENU when only this key is pressed and released, and both |
| 692 // press and release events are not handled by others. | 690 // press and release events are not handled by others. |
| 693 Accelerator accelerator(ui::VKEY_MENU, false, false, false); | 691 Accelerator accelerator(ui::VKEY_MENU, false, false, false); |
| 694 handled = GetFocusManager()->ProcessAccelerator(accelerator); | 692 handled = GetFocusManager()->ProcessAccelerator(accelerator); |
| 695 } | 693 } |
| 696 | 694 |
| 697 return handled; | 695 return handled; |
| 698 } | 696 } |
| 699 | 697 |
| 700 // static | 698 // static |
| 701 int WidgetGtk::GetFlagsForEventButton(const GdkEventButton& event) { | |
| 702 int flags = Event::GetFlagsFromGdkState(event.state); | |
| 703 switch (event.button) { | |
| 704 case 1: | |
| 705 flags |= ui::EF_LEFT_BUTTON_DOWN; | |
| 706 break; | |
| 707 case 2: | |
| 708 flags |= ui::EF_MIDDLE_BUTTON_DOWN; | |
| 709 break; | |
| 710 case 3: | |
| 711 flags |= ui::EF_RIGHT_BUTTON_DOWN; | |
| 712 break; | |
| 713 default: | |
| 714 // We only deal with 1-3. | |
| 715 break; | |
| 716 } | |
| 717 if (event.type == GDK_2BUTTON_PRESS) | |
| 718 flags |= ui::EF_IS_DOUBLE_CLICK; | |
| 719 return flags; | |
| 720 } | |
| 721 | |
| 722 // static | |
| 723 void WidgetGtk::EnableDebugPaint() { | 699 void WidgetGtk::EnableDebugPaint() { |
| 724 debug_paint_enabled_ = true; | 700 debug_paint_enabled_ = true; |
| 725 } | 701 } |
| 726 | 702 |
| 727 //////////////////////////////////////////////////////////////////////////////// | 703 //////////////////////////////////////////////////////////////////////////////// |
| 728 // WidgetGtk, NativeWidget implementation: | 704 // WidgetGtk, NativeWidget implementation: |
| 729 | 705 |
| 730 Widget* WidgetGtk::GetWidget() { | 706 Widget* WidgetGtk::GetWidget() { |
| 731 return this; | 707 return this; |
| 732 } | 708 } |
| 733 | 709 |
| 734 void WidgetGtk::SetNativeWindowProperty(const char* name, void* value) { | 710 void WidgetGtk::SetNativeWindowProperty(const char* name, void* value) { |
| 735 g_object_set_data(G_OBJECT(widget_), name, value); | 711 g_object_set_data(G_OBJECT(widget_), name, value); |
| 736 } | 712 } |
| 737 | 713 |
| 738 void* WidgetGtk::GetNativeWindowProperty(const char* name) { | 714 void* WidgetGtk::GetNativeWindowProperty(const char* name) { |
| 739 return g_object_get_data(G_OBJECT(widget_), name); | 715 return g_object_get_data(G_OBJECT(widget_), name); |
| 740 } | 716 } |
| 741 | 717 |
| 742 TooltipManager* WidgetGtk::GetTooltipManager() const { | 718 TooltipManager* WidgetGtk::GetTooltipManager() const { |
| 743 return tooltip_manager_.get(); | 719 return tooltip_manager_.get(); |
| 744 } | 720 } |
| 745 | 721 |
| 746 bool WidgetGtk::IsScreenReaderActive() const { | 722 bool WidgetGtk::IsScreenReaderActive() const { |
| 747 return false; | 723 return false; |
| 748 } | 724 } |
| 749 | 725 |
| 750 void WidgetGtk::SetNativeCapture() { | 726 void WidgetGtk::SetMouseCapture() { |
| 751 DCHECK(!HasNativeCapture()); | 727 DCHECK(!HasMouseCapture()); |
| 752 gtk_grab_add(window_contents_); | 728 gtk_grab_add(window_contents_); |
| 753 } | 729 } |
| 754 | 730 |
| 755 void WidgetGtk::ReleaseNativeCapture() { | 731 void WidgetGtk::ReleaseMouseCapture() { |
| 756 if (HasNativeCapture()) | 732 if (HasMouseCapture()) |
| 757 gtk_grab_remove(window_contents_); | 733 gtk_grab_remove(window_contents_); |
| 758 } | 734 } |
| 759 | 735 |
| 760 bool WidgetGtk::HasNativeCapture() const { | 736 bool WidgetGtk::HasMouseCapture() const { |
| 761 // TODO(beng): Should be able to use gtk_widget_has_grab() here but the | 737 // TODO(beng): Should be able to use gtk_widget_has_grab() here but the |
| 762 // trybots don't have Gtk 2.18. | 738 // trybots don't have Gtk 2.18. |
| 763 return GTK_WIDGET_HAS_GRAB(window_contents_); | 739 return GTK_WIDGET_HAS_GRAB(window_contents_); |
| 764 } | 740 } |
| 765 | 741 |
| 766 gfx::Rect WidgetGtk::GetWindowScreenBounds() const { | 742 gfx::Rect WidgetGtk::GetWindowScreenBounds() const { |
| 767 // Client == Window bounds on Gtk. | 743 // Client == Window bounds on Gtk. |
| 768 return GetClientAreaScreenBounds(); | 744 return GetClientAreaScreenBounds(); |
| 769 } | 745 } |
| 770 | 746 |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 GdkDragContext* context, | 1038 GdkDragContext* context, |
| 1063 gint x, | 1039 gint x, |
| 1064 gint y, | 1040 gint y, |
| 1065 guint time) { | 1041 guint time) { |
| 1066 if (!drop_target_.get()) | 1042 if (!drop_target_.get()) |
| 1067 drop_target_.reset(new DropTargetGtk(GetRootView(), context)); | 1043 drop_target_.reset(new DropTargetGtk(GetRootView(), context)); |
| 1068 return drop_target_->OnDragMotion(context, x, y, time); | 1044 return drop_target_->OnDragMotion(context, x, y, time); |
| 1069 } | 1045 } |
| 1070 | 1046 |
| 1071 gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { | 1047 gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { |
| 1072 if (last_mouse_event_was_move_ && last_mouse_move_x_ == event->x_root && | 1048 if (HasMouseCapture() && event->mode == GDK_CROSSING_GRAB) { |
| 1073 last_mouse_move_y_ == event->y_root) { | |
| 1074 // Don't generate a mouse event for the same location as the last. | |
| 1075 return false; | |
| 1076 } | |
| 1077 | |
| 1078 if (HasNativeCapture() && event->mode == GDK_CROSSING_GRAB) { | |
| 1079 // Doing a grab results an async enter event, regardless of where the mouse | 1049 // Doing a grab results an async enter event, regardless of where the mouse |
| 1080 // is. We don't want to generate a mouse move in this case. | 1050 // is. We don't want to generate a mouse move in this case. |
| 1081 return false; | 1051 return false; |
| 1082 } | 1052 } |
| 1083 | 1053 |
| 1084 if (!last_mouse_event_was_move_ && !is_mouse_down_) { | 1054 if (!last_mouse_event_was_move_ && !is_mouse_button_pressed_) { |
| 1085 // When a mouse button is pressed gtk generates a leave, enter, press. | 1055 // When a mouse button is pressed gtk generates a leave, enter, press. |
| 1086 // RootView expects to get a mouse move before a press, otherwise enter is | 1056 // RootView expects to get a mouse move before a press, otherwise enter is |
| 1087 // not set. So we generate a move here. | 1057 // not set. So we generate a move here. |
| 1088 last_mouse_move_x_ = event->x_root; | |
| 1089 last_mouse_move_y_ = event->y_root; | |
| 1090 last_mouse_event_was_move_ = true; | |
| 1091 | |
| 1092 int x = 0, y = 0; | 1058 int x = 0, y = 0; |
| 1093 GetContainedWidgetEventCoordinates(event, &x, &y); | 1059 GetContainedWidgetEventCoordinates(event, &x, &y); |
| 1060 int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); |
| 1094 | 1061 |
| 1095 // If this event is the result of pressing a button then one of the button | 1062 // If this event is the result of pressing a button then one of the button |
| 1096 // modifiers is set. Unset it as we're compensating for the leave generated | 1063 // modifiers is set. Unset it as we're compensating for the leave generated |
| 1097 // when you press a button. | 1064 // when you press a button. |
| 1098 int flags = (Event::GetFlagsFromGdkState(event->state) & | 1065 flags &= ~(ui::EF_LEFT_BUTTON_DOWN | |
| 1099 ~(ui::EF_LEFT_BUTTON_DOWN | | 1066 ui::EF_MIDDLE_BUTTON_DOWN | |
| 1100 ui::EF_MIDDLE_BUTTON_DOWN | | 1067 ui::EF_RIGHT_BUTTON_DOWN); |
| 1101 ui::EF_RIGHT_BUTTON_DOWN)); | 1068 |
| 1102 MouseEvent mouse_move(ui::ET_MOUSE_MOVED, x, y, flags); | 1069 MouseEvent mouse_move(ui::ET_MOUSE_MOVED, x, y, flags); |
| 1103 GetRootView()->OnMouseMoved(mouse_move); | 1070 delegate_->OnMouseEvent(mouse_move); |
| 1104 } | 1071 } |
| 1105 | 1072 |
| 1106 return false; | 1073 return false; |
| 1107 } | 1074 } |
| 1108 | 1075 |
| 1109 gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { | 1076 gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { |
| 1110 last_mouse_event_was_move_ = false; | 1077 last_mouse_event_was_move_ = false; |
| 1111 if (!HasNativeCapture() && !is_mouse_down_) { | 1078 if (!HasMouseCapture() && !is_mouse_button_pressed_) { |
| 1112 MouseEvent mouse_event(reinterpret_cast<GdkEvent*>(event)); | 1079 MouseEvent mouse_event(reinterpret_cast<GdkEvent*>(event)); |
| 1113 GetRootView()->OnMouseExited(mouse_event); | 1080 delegate_->OnMouseEvent(mouse_event); |
| 1114 } | 1081 } |
| 1115 return false; | 1082 return false; |
| 1116 } | 1083 } |
| 1117 | 1084 |
| 1118 gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { | 1085 gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { |
| 1119 int x = 0, y = 0; | 1086 int x = 0, y = 0; |
| 1120 GetContainedWidgetEventCoordinates(event, &x, &y); | 1087 GetContainedWidgetEventCoordinates(event, &x, &y); |
| 1121 | 1088 int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); |
| 1122 if (HasNativeCapture() && is_mouse_down_) { | 1089 MouseEvent mouse_event((HasMouseCapture() && is_mouse_button_pressed_) ? |
| 1123 last_mouse_event_was_move_ = false; | 1090 ui::ET_MOUSE_DRAGGED : ui::ET_MOUSE_MOVED, x, y, flags); |
| 1124 int flags = Event::GetFlagsFromGdkState(event->state); | 1091 delegate_->OnMouseEvent(mouse_event); |
| 1125 MouseEvent mouse_drag(ui::ET_MOUSE_DRAGGED, x, y, flags); | |
| 1126 GetRootView()->OnMouseDragged(mouse_drag); | |
| 1127 return true; | |
| 1128 } | |
| 1129 gfx::Point screen_loc(event->x_root, event->y_root); | |
| 1130 if (last_mouse_event_was_move_ && last_mouse_move_x_ == screen_loc.x() && | |
| 1131 last_mouse_move_y_ == screen_loc.y()) { | |
| 1132 // Don't generate a mouse event for the same location as the last. | |
| 1133 return true; | |
| 1134 } | |
| 1135 last_mouse_move_x_ = screen_loc.x(); | |
| 1136 last_mouse_move_y_ = screen_loc.y(); | |
| 1137 last_mouse_event_was_move_ = true; | |
| 1138 int flags = Event::GetFlagsFromGdkState(event->state); | |
| 1139 MouseEvent mouse_move(ui::ET_MOUSE_MOVED, x, y, flags); | |
| 1140 GetRootView()->OnMouseMoved(mouse_move); | |
| 1141 return true; | 1092 return true; |
| 1142 } | 1093 } |
| 1143 | 1094 |
| 1144 gboolean WidgetGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { | 1095 gboolean WidgetGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event) { |
| 1145 return ProcessMousePressed(event); | 1096 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { |
| 1097 // The sequence for double clicks is press, release, press, 2press, release. |
| 1098 // This means that at the time we get the second 'press' we don't know |
| 1099 // whether it corresponds to a double click or not. For now we're completely |
| 1100 // ignoring the 2press/3press events as they are duplicate. To make this |
| 1101 // work right we need to write our own code that detects if the press is a |
| 1102 // double/triple. For now we're completely punting, which means we always |
| 1103 // get single clicks. |
| 1104 // TODO: fix this. |
| 1105 return true; |
| 1106 } |
| 1107 |
| 1108 // An event may come from a contained widget which has its own gdk window. |
| 1109 // Translate it to the widget's coordinates. |
| 1110 int x = 0, y = 0; |
| 1111 GetContainedWidgetEventCoordinates(event, &x, &y); |
| 1112 int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); |
| 1113 MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, x, y, flags); |
| 1114 |
| 1115 // Returns true to consume the event when widget is not transparent. |
| 1116 return delegate_->OnMouseEvent(mouse_pressed) || !transparent_; |
| 1146 } | 1117 } |
| 1147 | 1118 |
| 1148 gboolean WidgetGtk::OnButtonRelease(GtkWidget* widget, GdkEventButton* event) { | 1119 gboolean WidgetGtk::OnButtonRelease(GtkWidget* widget, GdkEventButton* event) { |
| 1149 ProcessMouseReleased(event); | 1120 // GTK generates a mouse release at the end of dnd. We need to ignore it. |
| 1121 if (drag_data_) |
| 1122 return true; |
| 1123 |
| 1124 // An event may come from a contained widget which has its own gdk window. |
| 1125 // Translate it to the widget's coordinates. |
| 1126 int x = 0, y = 0; |
| 1127 GetContainedWidgetEventCoordinates(event, &x, &y); |
| 1128 int flags = Event::GetFlagsFromGdkEvent(reinterpret_cast<GdkEvent*>(event)); |
| 1129 MouseEvent mouse_up(ui::ET_MOUSE_RELEASED, x, y, flags); |
| 1130 delegate_->OnMouseEvent(mouse_up); |
| 1150 return true; | 1131 return true; |
| 1151 } | 1132 } |
| 1152 | 1133 |
| 1153 gboolean WidgetGtk::OnScroll(GtkWidget* widget, GdkEventScroll* event) { | 1134 gboolean WidgetGtk::OnScroll(GtkWidget* widget, GdkEventScroll* event) { |
| 1154 return ProcessScroll(event); | 1135 // An event may come from a contained widget which has its own gdk window. |
| 1136 // Translate it to the widget's coordinates. |
| 1137 int x = 0, y = 0; |
| 1138 GetContainedWidgetEventCoordinates(event, &x, &y); |
| 1139 GdkEventScroll translated_event = *event; |
| 1140 translated_event.x = x; |
| 1141 translated_event.y = y; |
| 1142 |
| 1143 MouseWheelEvent wheel_event(reinterpret_cast<GdkEvent*>(&translated_event)); |
| 1144 return GetRootView()->OnMouseWheel(wheel_event); |
| 1155 } | 1145 } |
| 1156 | 1146 |
| 1157 gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { | 1147 gboolean WidgetGtk::OnFocusIn(GtkWidget* widget, GdkEventFocus* event) { |
| 1158 if (has_focus_) | 1148 if (has_focus_) |
| 1159 return false; // This is the second focus-in event in a row, ignore it. | 1149 return false; // This is the second focus-in event in a row, ignore it. |
| 1160 has_focus_ = true; | 1150 has_focus_ = true; |
| 1161 | 1151 |
| 1162 should_handle_menu_key_release_ = false; | 1152 should_handle_menu_key_release_ = false; |
| 1163 | 1153 |
| 1164 if (type_ == TYPE_CHILD) | 1154 if (type_ == TYPE_CHILD) |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 // SchedulePaintInRect calls for the widget will have happened before the | 1263 // SchedulePaintInRect calls for the widget will have happened before the |
| 1274 // widget was drawable. This means that gtk_widget_queue_draw_area wasn't | 1264 // widget was drawable. This means that gtk_widget_queue_draw_area wasn't |
| 1275 // called, and so the widget will not get any expose events. Consequently, the | 1265 // called, and so the widget will not get any expose events. Consequently, the |
| 1276 // widget won't paint itself until something else triggers a paint call. | 1266 // widget won't paint itself until something else triggers a paint call. |
| 1277 gdk_window_process_updates(widget_->window, true); | 1267 gdk_window_process_updates(widget_->window, true); |
| 1278 } | 1268 } |
| 1279 | 1269 |
| 1280 void WidgetGtk::OnHide(GtkWidget* widget) { | 1270 void WidgetGtk::OnHide(GtkWidget* widget) { |
| 1281 } | 1271 } |
| 1282 | 1272 |
| 1283 bool WidgetGtk::ReleaseCaptureOnMouseReleased() { | |
| 1284 return true; | |
| 1285 } | |
| 1286 | |
| 1287 void WidgetGtk::HandleXGrabBroke() { | 1273 void WidgetGtk::HandleXGrabBroke() { |
| 1288 } | 1274 } |
| 1289 | 1275 |
| 1290 void WidgetGtk::HandleGtkGrabBroke() { | 1276 void WidgetGtk::HandleGtkGrabBroke() { |
| 1291 if (is_mouse_down_) | 1277 delegate_->OnMouseCaptureLost(); |
| 1292 GetRootView()->OnMouseCaptureLost(); | |
| 1293 is_mouse_down_ = false; | |
| 1294 } | 1278 } |
| 1295 | 1279 |
| 1296 //////////////////////////////////////////////////////////////////////////////// | 1280 //////////////////////////////////////////////////////////////////////////////// |
| 1297 // WidgetGtk, private: | 1281 // WidgetGtk, private: |
| 1298 | 1282 |
| 1299 RootView* WidgetGtk::CreateRootView() { | 1283 RootView* WidgetGtk::CreateRootView() { |
| 1300 return new RootView(this); | 1284 return new RootView(this); |
| 1301 } | 1285 } |
| 1302 | 1286 |
| 1303 gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { | 1287 gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { |
| 1304 DCHECK(window_contents_ && window_contents_->window); | 1288 DCHECK(window_contents_ && window_contents_->window); |
| 1305 return GDK_WINDOW_XID(window_contents_->window); | 1289 return GDK_WINDOW_XID(window_contents_->window); |
| 1306 } | 1290 } |
| 1307 | 1291 |
| 1308 gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { | 1292 gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { |
| 1309 // Clear the background to be totally transparent. We don't need to | 1293 // Clear the background to be totally transparent. We don't need to |
| 1310 // paint the root view here as that is done by OnPaint. | 1294 // paint the root view here as that is done by OnPaint. |
| 1311 DCHECK(transparent_); | 1295 DCHECK(transparent_); |
| 1312 DrawTransparentBackground(widget, event); | 1296 DrawTransparentBackground(widget, event); |
| 1313 return false; | 1297 return false; |
| 1314 } | 1298 } |
| 1315 | 1299 |
| 1316 bool WidgetGtk::ProcessMousePressed(GdkEventButton* event) { | |
| 1317 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { | |
| 1318 // The sequence for double clicks is press, release, press, 2press, release. | |
| 1319 // This means that at the time we get the second 'press' we don't know | |
| 1320 // whether it corresponds to a double click or not. For now we're completely | |
| 1321 // ignoring the 2press/3press events as they are duplicate. To make this | |
| 1322 // work right we need to write our own code that detects if the press is a | |
| 1323 // double/triple. For now we're completely punting, which means we always | |
| 1324 // get single clicks. | |
| 1325 // TODO: fix this. | |
| 1326 return true; | |
| 1327 } | |
| 1328 | |
| 1329 // An event may come from a contained widget which has its own gdk window. | |
| 1330 // Translate it to the widget's coordinates. | |
| 1331 int x = 0; | |
| 1332 int y = 0; | |
| 1333 GetContainedWidgetEventCoordinates(event, &x, &y); | |
| 1334 last_mouse_event_was_move_ = false; | |
| 1335 MouseEvent mouse_pressed(ui::ET_MOUSE_PRESSED, x, y, | |
| 1336 GetFlagsForEventButton(*event)); | |
| 1337 | |
| 1338 if (GetRootView()->OnMousePressed(mouse_pressed)) { | |
| 1339 is_mouse_down_ = true; | |
| 1340 if (!HasNativeCapture()) | |
| 1341 SetNativeCapture(); | |
| 1342 return true; | |
| 1343 } | |
| 1344 | |
| 1345 // Returns true to consume the event when widget is not transparent. | |
| 1346 return !transparent_; | |
| 1347 } | |
| 1348 | |
| 1349 void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) { | |
| 1350 int x = 0, y = 0; | |
| 1351 GetContainedWidgetEventCoordinates(event, &x, &y); | |
| 1352 | |
| 1353 last_mouse_event_was_move_ = false; | |
| 1354 MouseEvent mouse_up(ui::ET_MOUSE_RELEASED, x, y, | |
| 1355 GetFlagsForEventButton(*event)); | |
| 1356 // Release the capture first, that way we don't get confused if | |
| 1357 // OnMouseReleased blocks. | |
| 1358 if (HasNativeCapture() && ReleaseCaptureOnMouseReleased()) | |
| 1359 ReleaseNativeCapture(); | |
| 1360 is_mouse_down_ = false; | |
| 1361 // GTK generates a mouse release at the end of dnd. We need to ignore it. | |
| 1362 if (!drag_data_) | |
| 1363 GetRootView()->OnMouseReleased(mouse_up); | |
| 1364 } | |
| 1365 | |
| 1366 bool WidgetGtk::ProcessScroll(GdkEventScroll* event) { | |
| 1367 // An event may come from a contained widget which has its own gdk window. | |
| 1368 // Translate it to the widget's coordinates. | |
| 1369 int x = 0, y = 0; | |
| 1370 GetContainedWidgetEventCoordinates(event, &x, &y); | |
| 1371 GdkEventScroll translated_event = *event; | |
| 1372 translated_event.x = x; | |
| 1373 translated_event.y = y; | |
| 1374 | |
| 1375 MouseWheelEvent wheel_event(reinterpret_cast<GdkEvent*>(&translated_event)); | |
| 1376 return GetRootView()->OnMouseWheel(wheel_event); | |
| 1377 } | |
| 1378 | |
| 1379 // static | 1300 // static |
| 1380 Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { | 1301 Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { |
| 1381 GtkWidget* parent = widget; | 1302 GtkWidget* parent = widget; |
| 1382 while (parent) { | 1303 while (parent) { |
| 1383 WidgetGtk* widget_gtk = static_cast<WidgetGtk*>( | 1304 WidgetGtk* widget_gtk = static_cast<WidgetGtk*>( |
| 1384 NativeWidget::GetNativeWidgetForNativeView(parent)); | 1305 NativeWidget::GetNativeWidgetForNativeView(parent)); |
| 1385 if (widget_gtk && widget_gtk->is_window_) | 1306 if (widget_gtk && widget_gtk->is_window_) |
| 1386 return static_cast<WindowGtk*>(widget_gtk); | 1307 return static_cast<WindowGtk*>(widget_gtk); |
| 1387 parent = gtk_widget_get_parent(parent); | 1308 parent = gtk_widget_get_parent(parent); |
| 1388 } | 1309 } |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1644 | 1565 |
| 1645 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); | 1566 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); |
| 1646 if (native_widget) | 1567 if (native_widget) |
| 1647 children->insert(native_widget); | 1568 children->insert(native_widget); |
| 1648 gtk_container_foreach(GTK_CONTAINER(native_view), | 1569 gtk_container_foreach(GTK_CONTAINER(native_view), |
| 1649 EnumerateChildWidgetsForNativeWidgets, | 1570 EnumerateChildWidgetsForNativeWidgets, |
| 1650 reinterpret_cast<gpointer>(children)); | 1571 reinterpret_cast<gpointer>(children)); |
| 1651 } | 1572 } |
| 1652 | 1573 |
| 1653 } // namespace views | 1574 } // namespace views |
| OLD | NEW |