Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "app/gfx/path.h" | 7 #include "app/gfx/path.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "views/fill_layout.h" | 9 #include "views/fill_layout.h" |
| 10 #include "views/widget/default_theme_provider.h" | 10 #include "views/widget/default_theme_provider.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 break; | 46 break; |
| 47 default: | 47 default: |
| 48 // We only deal with 1-3. | 48 // We only deal with 1-3. |
| 49 break; | 49 break; |
| 50 } | 50 } |
| 51 if (event.type == GDK_2BUTTON_PRESS) | 51 if (event.type == GDK_2BUTTON_PRESS) |
| 52 flags |= MouseEvent::EF_IS_DOUBLE_CLICK; | 52 flags |= MouseEvent::EF_IS_DOUBLE_CLICK; |
| 53 return flags; | 53 return flags; |
| 54 } | 54 } |
| 55 | 55 |
| 56 // static | |
| 57 GtkWidget* WidgetGtk::null_parent_ = NULL; | |
| 58 | |
| 56 //////////////////////////////////////////////////////////////////////////////// | 59 //////////////////////////////////////////////////////////////////////////////// |
| 57 // WidgetGtk, public: | 60 // WidgetGtk, public: |
| 58 | 61 |
| 59 WidgetGtk::WidgetGtk(Type type) | 62 WidgetGtk::WidgetGtk(Type type) |
| 60 : is_window_(false), | 63 : is_window_(false), |
| 61 type_(type), | 64 type_(type), |
| 62 widget_(NULL), | 65 widget_(NULL), |
| 63 child_widget_parent_(NULL), | 66 window_contents_(NULL), |
| 64 is_mouse_down_(false), | 67 is_mouse_down_(false), |
| 65 has_capture_(false), | 68 has_capture_(false), |
| 66 last_mouse_event_was_move_(false), | 69 last_mouse_event_was_move_(false), |
| 67 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), | 70 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
| 68 delete_on_destroy_(true), | 71 delete_on_destroy_(true), |
| 69 transparent_(false) { | 72 transparent_(false) { |
| 70 } | 73 } |
| 71 | 74 |
| 72 WidgetGtk::~WidgetGtk() { | 75 WidgetGtk::~WidgetGtk() { |
| 73 MessageLoopForUI::current()->RemoveObserver(this); | 76 MessageLoopForUI::current()->RemoveObserver(this); |
| 74 } | 77 } |
| 75 | 78 |
| 76 void WidgetGtk::Init(GtkWidget* parent, | 79 void WidgetGtk::Init(GtkWidget* parent, |
| 77 const gfx::Rect& bounds, | 80 const gfx::Rect& bounds, |
| 78 bool has_own_focus_manager) { | 81 bool has_own_focus_manager) { |
| 79 // Force creation of the RootView if it hasn't been created yet. | 82 // Force creation of the RootView if it hasn't been created yet. |
| 80 GetRootView(); | 83 GetRootView(); |
| 81 | 84 |
| 82 #if !defined(LINUX2) | 85 #if !defined(LINUX2) |
| 83 default_theme_provider_.reset(new DefaultThemeProvider()); | 86 default_theme_provider_.reset(new DefaultThemeProvider()); |
| 84 #endif | 87 #endif |
| 85 | 88 |
| 86 // Make container here. | 89 // Make container here. |
| 87 CreateGtkWidget(); | 90 CreateGtkWidget(parent); |
| 88 | 91 |
| 89 // Make sure we receive our motion events. | 92 // Make sure we receive our motion events. |
| 90 | 93 |
| 91 // In general we register most events on the parent of all widgets. At a | 94 // In general we register most events on the parent of all widgets. At a |
| 92 // minimum we need painting to happen on the parent (otherwise painting | 95 // minimum we need painting to happen on the parent (otherwise painting |
| 93 // doesn't work at all), and similarly we need mouse release events on the | 96 // doesn't work at all), and similarly we need mouse release events on the |
| 94 // parent as windows don't get mouse releases. | 97 // parent as windows don't get mouse releases. |
| 95 gtk_widget_add_events(child_widget_parent_, | 98 gtk_widget_add_events(window_contents_, |
| 96 GDK_ENTER_NOTIFY_MASK | | 99 GDK_ENTER_NOTIFY_MASK | |
| 97 GDK_LEAVE_NOTIFY_MASK | | 100 GDK_LEAVE_NOTIFY_MASK | |
| 98 GDK_BUTTON_PRESS_MASK | | 101 GDK_BUTTON_PRESS_MASK | |
| 99 GDK_BUTTON_RELEASE_MASK | | 102 GDK_BUTTON_RELEASE_MASK | |
| 100 GDK_POINTER_MOTION_MASK | | 103 GDK_POINTER_MOTION_MASK | |
| 101 GDK_KEY_PRESS_MASK | | 104 GDK_KEY_PRESS_MASK | |
| 102 GDK_KEY_RELEASE_MASK); | 105 GDK_KEY_RELEASE_MASK); |
| 103 | 106 |
| 104 root_view_->OnWidgetCreated(); | 107 root_view_->OnWidgetCreated(); |
| 105 | 108 |
| 106 // TODO(port): if(has_own_focus_manager) block | 109 // TODO(port): if(has_own_focus_manager) block |
| 107 | 110 |
| 108 SetRootViewForWidget(widget_, root_view_.get()); | 111 SetRootViewForWidget(widget_, root_view_.get()); |
| 109 | 112 |
| 110 MessageLoopForUI::current()->AddObserver(this); | 113 MessageLoopForUI::current()->AddObserver(this); |
| 111 | 114 |
| 112 g_signal_connect_after(G_OBJECT(child_widget_parent_), "size_allocate", | 115 // TODO(beng): make these take this rather than NULL. |
| 116 g_signal_connect_after(G_OBJECT(window_contents_), "size_allocate", | |
| 113 G_CALLBACK(CallSizeAllocate), NULL); | 117 G_CALLBACK(CallSizeAllocate), NULL); |
| 114 g_signal_connect(G_OBJECT(child_widget_parent_), "expose_event", | 118 g_signal_connect(G_OBJECT(window_contents_), "expose_event", |
| 115 G_CALLBACK(CallPaint), NULL); | 119 G_CALLBACK(CallPaint), NULL); |
| 116 g_signal_connect(G_OBJECT(child_widget_parent_), "enter_notify_event", | 120 g_signal_connect(G_OBJECT(window_contents_), "enter_notify_event", |
| 117 G_CALLBACK(CallEnterNotify), NULL); | 121 G_CALLBACK(CallEnterNotify), NULL); |
| 118 g_signal_connect(G_OBJECT(child_widget_parent_), "leave_notify_event", | 122 g_signal_connect(G_OBJECT(window_contents_), "leave_notify_event", |
| 119 G_CALLBACK(CallLeaveNotify), NULL); | 123 G_CALLBACK(CallLeaveNotify), NULL); |
| 120 g_signal_connect(G_OBJECT(child_widget_parent_), "motion_notify_event", | 124 g_signal_connect(G_OBJECT(window_contents_), "motion_notify_event", |
| 121 G_CALLBACK(CallMotionNotify), NULL); | 125 G_CALLBACK(CallMotionNotify), NULL); |
| 122 g_signal_connect(G_OBJECT(child_widget_parent_), "button_press_event", | 126 g_signal_connect(G_OBJECT(window_contents_), "button_press_event", |
| 123 G_CALLBACK(CallButtonPress), NULL); | 127 G_CALLBACK(CallButtonPress), NULL); |
| 124 g_signal_connect(G_OBJECT(child_widget_parent_), "button_release_event", | 128 g_signal_connect(G_OBJECT(window_contents_), "button_release_event", |
| 125 G_CALLBACK(CallButtonRelease), NULL); | 129 G_CALLBACK(CallButtonRelease), NULL); |
| 126 g_signal_connect(G_OBJECT(child_widget_parent_), "grab_broken_event", | 130 g_signal_connect(G_OBJECT(window_contents_), "focus_out_event", |
| 131 G_CALLBACK(CallFocusOut), NULL); | |
| 132 g_signal_connect(G_OBJECT(window_contents_), "grab_broken_event", | |
| 127 G_CALLBACK(CallGrabBrokeEvent), NULL); | 133 G_CALLBACK(CallGrabBrokeEvent), NULL); |
| 128 g_signal_connect(G_OBJECT(child_widget_parent_), "grab_notify", | 134 g_signal_connect(G_OBJECT(window_contents_), "grab_notify", |
| 129 G_CALLBACK(CallGrabNotify), NULL); | 135 G_CALLBACK(CallGrabNotify), NULL); |
| 130 g_signal_connect(G_OBJECT(child_widget_parent_), "focus_out_event", | 136 g_signal_connect(G_OBJECT(window_contents_), "key_press_event", |
| 131 G_CALLBACK(CallFocusOut), NULL); | |
| 132 g_signal_connect(G_OBJECT(child_widget_parent_), "key_press_event", | |
| 133 G_CALLBACK(CallKeyPress), NULL); | 137 G_CALLBACK(CallKeyPress), NULL); |
| 134 g_signal_connect(G_OBJECT(child_widget_parent_), "key_release_event", | 138 g_signal_connect(G_OBJECT(window_contents_), "key_release_event", |
| 135 G_CALLBACK(CallKeyRelease), NULL); | 139 G_CALLBACK(CallKeyRelease), NULL); |
| 136 g_signal_connect(G_OBJECT(child_widget_parent_), "scroll_event", | 140 g_signal_connect(G_OBJECT(window_contents_), "scroll_event", |
| 137 G_CALLBACK(CallScroll), NULL); | 141 G_CALLBACK(CallScroll), NULL); |
| 138 g_signal_connect(G_OBJECT(child_widget_parent_), "visibility_notify_event", | 142 g_signal_connect(G_OBJECT(window_contents_), "visibility_notify_event", |
| 139 G_CALLBACK(CallVisibilityNotify), NULL); | 143 G_CALLBACK(CallVisibilityNotify), NULL); |
| 140 | 144 |
| 141 // In order to receive notification when the window is no longer the front | 145 // In order to receive notification when the window is no longer the front |
| 142 // window, we need to install these on the widget. | 146 // window, we need to install these on the widget. |
| 143 // NOTE: this doesn't work with focus follows mouse. | 147 // NOTE: this doesn't work with focus follows mouse. |
| 144 g_signal_connect(G_OBJECT(widget_), "focus_in_event", | 148 g_signal_connect(G_OBJECT(widget_), "focus_in_event", |
| 145 G_CALLBACK(CallFocusIn), NULL); | 149 G_CALLBACK(CallFocusIn), NULL); |
| 146 g_signal_connect(G_OBJECT(widget_), "focus_out_event", | 150 g_signal_connect(G_OBJECT(widget_), "focus_out_event", |
| 147 G_CALLBACK(CallFocusOut), NULL); | 151 G_CALLBACK(CallFocusOut), NULL); |
| 148 | 152 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 160 // g_signal_connect(G_OBJECT(widget_), "drag_leave", | 164 // g_signal_connect(G_OBJECT(widget_), "drag_leave", |
| 161 // G_CALLBACK(drag_leave_event_cb), NULL); | 165 // G_CALLBACK(drag_leave_event_cb), NULL); |
| 162 // g_signal_connect(G_OBJECT(widget_), "drag_drop", | 166 // g_signal_connect(G_OBJECT(widget_), "drag_drop", |
| 163 // G_CALLBACK(drag_drop_event_cb), NULL); | 167 // G_CALLBACK(drag_drop_event_cb), NULL); |
| 164 // g_signal_connect(G_OBJECT(widget_), "drag_data_received", | 168 // g_signal_connect(G_OBJECT(widget_), "drag_data_received", |
| 165 // G_CALLBACK(drag_data_received_event_cb), NULL); | 169 // G_CALLBACK(drag_data_received_event_cb), NULL); |
| 166 | 170 |
| 167 tooltip_manager_.reset(new TooltipManagerGtk(this)); | 171 tooltip_manager_.reset(new TooltipManagerGtk(this)); |
| 168 | 172 |
| 169 if (type_ == TYPE_CHILD) { | 173 if (type_ == TYPE_CHILD) { |
| 170 WidgetGtk* parent_widget = GetViewForNative(parent); | 174 if (parent) { |
| 171 parent_widget->AddChild(widget_); | 175 WidgetGtk* parent_widget = GetViewForNative(parent); |
| 172 parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), | 176 parent_widget->AddChild(widget_); |
| 173 bounds.width(), bounds.height()); | 177 parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), |
| 178 bounds.width(), bounds.height()); | |
|
sky
2009/06/16 16:01:45
I think you need to persist the bounds some how, o
Ben Goodger (Google)
2009/06/16 19:53:46
It seems like the bounds setting will be done when
| |
| 179 } | |
| 174 } else { | 180 } else { |
| 175 if (bounds.width() > 0 && bounds.height() > 0) | 181 if (bounds.width() > 0 && bounds.height() > 0) |
| 176 gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height()); | 182 gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height()); |
| 177 gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y()); | 183 gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y()); |
| 178 } | 184 } |
| 179 } | 185 } |
| 180 | 186 |
| 181 bool WidgetGtk::MakeTransparent() { | 187 bool WidgetGtk::MakeTransparent() { |
| 182 // Transparency can only be enabled for windows/popups and only if we haven't | 188 // Transparency can only be enabled for windows/popups and only if we haven't |
| 183 // realized the widget. | 189 // realized the widget. |
| 184 DCHECK(!widget_ && type_ != TYPE_CHILD); | 190 DCHECK(!widget_ && type_ != TYPE_CHILD); |
| 185 | 191 |
| 186 if (!gdk_screen_is_composited(gdk_screen_get_default())) { | 192 if (!gdk_screen_is_composited(gdk_screen_get_default())) { |
| 187 // Transparency is only supported for compositing window managers. | 193 // Transparency is only supported for compositing window managers. |
| 188 DLOG(WARNING) << "compsiting not supported"; | 194 DLOG(WARNING) << "compsiting not supported"; |
| 189 return false; | 195 return false; |
| 190 } | 196 } |
| 191 | 197 |
| 192 if (!gdk_screen_get_rgba_colormap(gdk_screen_get_default())) { | 198 if (!gdk_screen_get_rgba_colormap(gdk_screen_get_default())) { |
| 193 // We need rgba to make the window transparent. | 199 // We need rgba to make the window transparent. |
| 194 return false; | 200 return false; |
| 195 } | 201 } |
| 196 | 202 |
| 197 transparent_ = true; | 203 transparent_ = true; |
| 198 return true; | 204 return true; |
| 199 } | 205 } |
| 200 | 206 |
| 201 void WidgetGtk::AddChild(GtkWidget* child) { | 207 void WidgetGtk::AddChild(GtkWidget* child) { |
| 202 gtk_container_add(GTK_CONTAINER(child_widget_parent_), child); | 208 gtk_container_add(GTK_CONTAINER(window_contents_), child); |
| 203 } | 209 } |
| 204 | 210 |
| 205 void WidgetGtk::RemoveChild(GtkWidget* child) { | 211 void WidgetGtk::RemoveChild(GtkWidget* child) { |
| 206 gtk_container_remove(GTK_CONTAINER(child_widget_parent_), child); | 212 gtk_container_remove(GTK_CONTAINER(window_contents_), child); |
| 213 } | |
| 214 | |
| 215 void WidgetGtk::ReparentChild(GtkWidget* child) { | |
| 216 gtk_widget_reparent(child, window_contents_); | |
| 207 } | 217 } |
| 208 | 218 |
| 209 void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) { | 219 void WidgetGtk::PositionChild(GtkWidget* child, int x, int y, int w, int h) { |
| 210 GtkAllocation alloc = { x, y, w, h }; | 220 GtkAllocation alloc = { x, y, w, h }; |
| 211 // For some reason we need to do both of these to size a widget. | 221 // For some reason we need to do both of these to size a widget. |
| 212 gtk_widget_size_allocate(child, &alloc); | 222 gtk_widget_size_allocate(child, &alloc); |
| 213 gtk_widget_set_size_request(child, w, h); | 223 gtk_widget_set_size_request(child, w, h); |
| 214 gtk_fixed_move(GTK_FIXED(child_widget_parent_), child, x, y); | 224 gtk_fixed_move(GTK_FIXED(window_contents_), child, x, y); |
| 215 } | 225 } |
| 216 | 226 |
| 217 void WidgetGtk::SetContentsView(View* view) { | 227 void WidgetGtk::SetContentsView(View* view) { |
| 218 DCHECK(view && widget_) | 228 DCHECK(view && widget_) |
| 219 << "Can't be called until after the HWND is created!"; | 229 << "Can't be called until after the HWND is created!"; |
| 220 // The ContentsView must be set up _after_ the window is created so that its | 230 // The ContentsView must be set up _after_ the window is created so that its |
| 221 // Widget pointer is valid. | 231 // Widget pointer is valid. |
| 222 root_view_->SetLayoutManager(new FillLayout); | 232 root_view_->SetLayoutManager(new FillLayout); |
| 223 if (root_view_->GetChildViewCount() != 0) | 233 if (root_view_->GetChildViewCount() != 0) |
| 224 root_view_->RemoveAllChildViews(true); | 234 root_view_->RemoveAllChildViews(true); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 // WidgetGtk, MessageLoopForUI::Observer implementation: | 392 // WidgetGtk, MessageLoopForUI::Observer implementation: |
| 383 | 393 |
| 384 void WidgetGtk::DidProcessEvent(GdkEvent* event) { | 394 void WidgetGtk::DidProcessEvent(GdkEvent* event) { |
| 385 if (root_view_->NeedsPainting(true)) | 395 if (root_view_->NeedsPainting(true)) |
| 386 PaintNow(root_view_->GetScheduledPaintRect()); | 396 PaintNow(root_view_->GetScheduledPaintRect()); |
| 387 } | 397 } |
| 388 | 398 |
| 389 //////////////////////////////////////////////////////////////////////////////// | 399 //////////////////////////////////////////////////////////////////////////////// |
| 390 // TODO(beng): organize into sections: | 400 // TODO(beng): organize into sections: |
| 391 | 401 |
| 392 void WidgetGtk::CreateGtkWidget() { | 402 void WidgetGtk::CreateGtkWidget(GtkWidget* parent) { |
| 393 if (type_ == TYPE_CHILD) { | 403 if (type_ == TYPE_CHILD) { |
| 394 child_widget_parent_ = widget_ = gtk_fixed_new(); | 404 window_contents_ = widget_ = gtk_fixed_new(); |
| 395 gtk_fixed_set_has_window(GTK_FIXED(widget_), true); | 405 gtk_fixed_set_has_window(GTK_FIXED(widget_), true); |
| 406 if (!parent && !null_parent_) { | |
| 407 GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP); | |
| 408 null_parent_ = gtk_fixed_new(); | |
| 409 gtk_container_add(GTK_CONTAINER(popup), null_parent_); | |
| 410 gtk_widget_realize(null_parent_); | |
| 411 } | |
| 412 gtk_container_add(GTK_CONTAINER(parent ? parent : null_parent_), widget_); | |
| 396 SetViewForNative(widget_, this); | 413 SetViewForNative(widget_, this); |
| 397 } else { | 414 } else { |
| 398 widget_ = gtk_window_new( | 415 widget_ = gtk_window_new( |
| 399 type_ == TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP); | 416 type_ == TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP); |
| 400 gtk_window_set_decorated(GTK_WINDOW(widget_), false); | 417 gtk_window_set_decorated(GTK_WINDOW(widget_), false); |
| 401 // We'll take care of positioning our window. | 418 // We'll take care of positioning our window. |
| 402 gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); | 419 gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); |
| 403 SetWindowForNative(widget_, static_cast<WindowGtk*>(this)); | 420 SetWindowForNative(widget_, static_cast<WindowGtk*>(this)); |
| 404 SetViewForNative(widget_, this); | 421 SetViewForNative(widget_, this); |
| 405 | 422 |
| 406 child_widget_parent_ = gtk_fixed_new(); | 423 window_contents_ = gtk_fixed_new(); |
| 407 gtk_fixed_set_has_window(GTK_FIXED(child_widget_parent_), true); | 424 gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); |
| 408 gtk_container_add(GTK_CONTAINER(widget_), child_widget_parent_); | 425 gtk_container_add(GTK_CONTAINER(widget_), window_contents_); |
| 409 gtk_widget_show(child_widget_parent_); | 426 gtk_widget_show(window_contents_); |
| 410 SetViewForNative(child_widget_parent_, this); | 427 SetViewForNative(window_contents_, this); |
| 411 | 428 |
| 412 if (transparent_) | 429 if (transparent_) |
| 413 ConfigureWidgetForTransparentBackground(); | 430 ConfigureWidgetForTransparentBackground(); |
| 414 } | 431 } |
| 415 | |
| 416 // The widget needs to be realized before handlers like size-allocate can | 432 // The widget needs to be realized before handlers like size-allocate can |
| 417 // function properly. | 433 // function properly. |
| 418 gtk_widget_realize(widget_); | 434 gtk_widget_realize(widget_); |
| 419 } | 435 } |
| 420 | 436 |
| 421 void WidgetGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { | 437 void WidgetGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { |
| 422 root_view_->SetBounds(0, 0, allocation->width, allocation->height); | 438 root_view_->SetBounds(0, 0, allocation->width, allocation->height); |
| 423 root_view_->Layout(); | 439 root_view_->Layout(); |
| 424 root_view_->SchedulePaint(); | 440 root_view_->SchedulePaint(); |
| 425 } | 441 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 KeyEvent key_event(event); | 509 KeyEvent key_event(event); |
| 494 return root_view_->ProcessKeyEvent(key_event); | 510 return root_view_->ProcessKeyEvent(key_event); |
| 495 } | 511 } |
| 496 | 512 |
| 497 gboolean WidgetGtk::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) { | 513 gboolean WidgetGtk::OnGrabBrokeEvent(GtkWidget* widget, GdkEvent* event) { |
| 498 HandleGrabBroke(); | 514 HandleGrabBroke(); |
| 499 return false; // To let other widgets get the event. | 515 return false; // To let other widgets get the event. |
| 500 } | 516 } |
| 501 | 517 |
| 502 void WidgetGtk::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) { | 518 void WidgetGtk::OnGrabNotify(GtkWidget* widget, gboolean was_grabbed) { |
| 503 gtk_grab_remove(child_widget_parent_); | 519 gtk_grab_remove(window_contents_); |
| 504 HandleGrabBroke(); | 520 HandleGrabBroke(); |
| 505 } | 521 } |
| 506 | 522 |
| 507 void WidgetGtk::OnDestroy(GtkWidget* widget) { | 523 void WidgetGtk::OnDestroy(GtkWidget* widget) { |
| 508 widget_ = child_widget_parent_ = NULL; | 524 widget_ = window_contents_ = NULL; |
| 509 root_view_->OnWidgetDestroyed(); | 525 root_view_->OnWidgetDestroyed(); |
| 510 if (delete_on_destroy_) | 526 if (delete_on_destroy_) |
| 511 delete this; | 527 delete this; |
| 512 } | 528 } |
| 513 | 529 |
| 514 // static | 530 // static |
| 515 WindowGtk* WidgetGtk::GetWindowForNative(GtkWidget* widget) { | 531 WindowGtk* WidgetGtk::GetWindowForNative(GtkWidget* widget) { |
| 516 gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-window"); | 532 gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-window"); |
| 517 return static_cast<WindowGtk*>(user_data); | 533 return static_cast<WindowGtk*>(user_data); |
| 518 } | 534 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 return true; | 573 return true; |
| 558 } | 574 } |
| 559 | 575 |
| 560 last_mouse_event_was_move_ = false; | 576 last_mouse_event_was_move_ = false; |
| 561 MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED, event->x, event->y, | 577 MouseEvent mouse_pressed(Event::ET_MOUSE_PRESSED, event->x, event->y, |
| 562 GetFlagsForEventButton(*event)); | 578 GetFlagsForEventButton(*event)); |
| 563 if (root_view_->OnMousePressed(mouse_pressed)) { | 579 if (root_view_->OnMousePressed(mouse_pressed)) { |
| 564 is_mouse_down_ = true; | 580 is_mouse_down_ = true; |
| 565 if (!has_capture_) { | 581 if (!has_capture_) { |
| 566 has_capture_ = true; | 582 has_capture_ = true; |
| 567 gtk_grab_add(child_widget_parent_); | 583 gtk_grab_add(window_contents_); |
| 568 } | 584 } |
| 569 return true; | 585 return true; |
| 570 } | 586 } |
| 571 | 587 |
| 572 return false; | 588 return false; |
| 573 } | 589 } |
| 574 | 590 |
| 575 void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) { | 591 void WidgetGtk::ProcessMouseReleased(GdkEventButton* event) { |
| 576 last_mouse_event_was_move_ = false; | 592 last_mouse_event_was_move_ = false; |
| 577 MouseEvent mouse_up(Event::ET_MOUSE_RELEASED, event->x, event->y, | 593 MouseEvent mouse_up(Event::ET_MOUSE_RELEASED, event->x, event->y, |
| 578 GetFlagsForEventButton(*event)); | 594 GetFlagsForEventButton(*event)); |
| 579 // Release the capture first, that way we don't get confused if | 595 // Release the capture first, that way we don't get confused if |
| 580 // OnMouseReleased blocks. | 596 // OnMouseReleased blocks. |
| 581 | 597 |
| 582 if (has_capture_ && ReleaseCaptureOnMouseReleased()) { | 598 if (has_capture_ && ReleaseCaptureOnMouseReleased()) { |
| 583 has_capture_ = false; | 599 has_capture_ = false; |
| 584 gtk_grab_remove(child_widget_parent_); | 600 gtk_grab_remove(window_contents_); |
| 585 } | 601 } |
| 586 is_mouse_down_ = false; | 602 is_mouse_down_ = false; |
| 587 root_view_->OnMouseReleased(mouse_up, false); | 603 root_view_->OnMouseReleased(mouse_up, false); |
| 588 } | 604 } |
| 589 | 605 |
| 590 // static | 606 // static |
| 591 WidgetGtk* WidgetGtk::GetViewForNative(GtkWidget* widget) { | 607 WidgetGtk* WidgetGtk::GetViewForNative(GtkWidget* widget) { |
| 592 gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-views"); | 608 gpointer user_data = g_object_get_data(G_OBJECT(widget), "chrome-views"); |
| 593 return static_cast<WidgetGtk*>(user_data); | 609 return static_cast<WidgetGtk*>(user_data); |
| 594 } | 610 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 756 while (parent) { | 772 while (parent) { |
| 757 WidgetGtk* widget_gtk = GetViewForNative(parent); | 773 WidgetGtk* widget_gtk = GetViewForNative(parent); |
| 758 if (widget_gtk && widget_gtk->is_window_) | 774 if (widget_gtk && widget_gtk->is_window_) |
| 759 return static_cast<WindowGtk*>(widget_gtk); | 775 return static_cast<WindowGtk*>(widget_gtk); |
| 760 parent = gtk_widget_get_parent(parent); | 776 parent = gtk_widget_get_parent(parent); |
| 761 } | 777 } |
| 762 return NULL; | 778 return NULL; |
| 763 } | 779 } |
| 764 | 780 |
| 765 void WidgetGtk::ConfigureWidgetForTransparentBackground() { | 781 void WidgetGtk::ConfigureWidgetForTransparentBackground() { |
| 766 DCHECK(widget_ && child_widget_parent_ && | 782 DCHECK(widget_ && window_contents_ && widget_ != window_contents_); |
| 767 widget_ != child_widget_parent_); | |
| 768 | 783 |
| 769 GdkColormap* rgba_colormap = | 784 GdkColormap* rgba_colormap = |
| 770 gdk_screen_get_rgba_colormap(gdk_screen_get_default()); | 785 gdk_screen_get_rgba_colormap(gdk_screen_get_default()); |
| 771 if (!rgba_colormap) { | 786 if (!rgba_colormap) { |
| 772 transparent_ = false; | 787 transparent_ = false; |
| 773 return; | 788 return; |
| 774 } | 789 } |
| 775 // To make the background transparent we need to install the RGBA colormap | 790 // To make the background transparent we need to install the RGBA colormap |
| 776 // on both the window and fixed. In addition we need to turn off double | 791 // on both the window and fixed. In addition we need to turn off double |
| 777 // buffering and make sure no decorations are drawn. The last bit is to make | 792 // buffering and make sure no decorations are drawn. The last bit is to make |
| 778 // sure the widget doesn't attempt to draw a pixmap in it's background. | 793 // sure the widget doesn't attempt to draw a pixmap in it's background. |
| 779 gtk_widget_set_colormap(widget_, rgba_colormap); | 794 gtk_widget_set_colormap(widget_, rgba_colormap); |
| 780 gtk_widget_set_app_paintable(widget_, true); | 795 gtk_widget_set_app_paintable(widget_, true); |
| 781 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); | 796 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); |
| 782 gtk_widget_realize(widget_); | 797 gtk_widget_realize(widget_); |
| 783 gdk_window_set_decorations(widget_->window, | 798 gdk_window_set_decorations(widget_->window, |
| 784 static_cast<GdkWMDecoration>(0)); | 799 static_cast<GdkWMDecoration>(0)); |
| 785 // Widget must be realized before setting pixmap. | 800 // Widget must be realized before setting pixmap. |
| 786 gdk_window_set_back_pixmap(widget_->window, NULL, FALSE); | 801 gdk_window_set_back_pixmap(widget_->window, NULL, FALSE); |
| 787 | 802 |
| 788 gtk_widget_set_colormap(child_widget_parent_, rgba_colormap); | 803 gtk_widget_set_colormap(window_contents_, rgba_colormap); |
| 789 gtk_widget_set_app_paintable(child_widget_parent_, true); | 804 gtk_widget_set_app_paintable(window_contents_, true); |
| 790 GTK_WIDGET_UNSET_FLAGS(child_widget_parent_, GTK_DOUBLE_BUFFERED); | 805 GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); |
| 791 gtk_widget_realize(child_widget_parent_); | 806 gtk_widget_realize(window_contents_); |
| 792 // Widget must be realized before setting pixmap. | 807 // Widget must be realized before setting pixmap. |
| 793 gdk_window_set_back_pixmap(child_widget_parent_->window, NULL, FALSE); | 808 gdk_window_set_back_pixmap(window_contents_->window, NULL, FALSE); |
| 794 } | 809 } |
| 795 | 810 |
| 796 void WidgetGtk::HandleGrabBroke() { | 811 void WidgetGtk::HandleGrabBroke() { |
| 797 if (has_capture_) { | 812 if (has_capture_) { |
| 798 if (is_mouse_down_) | 813 if (is_mouse_down_) |
| 799 root_view_->ProcessMouseDragCanceled(); | 814 root_view_->ProcessMouseDragCanceled(); |
| 800 is_mouse_down_ = false; | 815 is_mouse_down_ = false; |
| 801 has_capture_ = false; | 816 has_capture_ = false; |
| 802 } | 817 } |
| 803 } | 818 } |
| 804 | 819 |
| 805 } // namespace views | 820 } // namespace views |
| OLD | NEW |