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 #include <X11/Xatom.h> | 10 #include <X11/Xatom.h> |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 return drag_widget; | 277 return drag_widget; |
278 } | 278 } |
279 | 279 |
280 // static | 280 // static |
281 GtkWidget* WidgetGtk::null_parent_ = NULL; | 281 GtkWidget* WidgetGtk::null_parent_ = NULL; |
282 bool WidgetGtk::debug_paint_enabled_ = false; | 282 bool WidgetGtk::debug_paint_enabled_ = false; |
283 | 283 |
284 //////////////////////////////////////////////////////////////////////////////// | 284 //////////////////////////////////////////////////////////////////////////////// |
285 // WidgetGtk, public: | 285 // WidgetGtk, public: |
286 | 286 |
287 WidgetGtk::WidgetGtk() | 287 WidgetGtk::WidgetGtk(internal::NativeWidgetDelegate* delegate) |
288 : is_window_(false), | 288 : is_window_(false), |
289 ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)), | 289 delegate_(delegate), |
290 widget_(NULL), | 290 widget_(NULL), |
291 window_contents_(NULL), | 291 window_contents_(NULL), |
292 child_(false), | 292 child_(false), |
293 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), | 293 ALLOW_THIS_IN_INITIALIZER_LIST(close_widget_factory_(this)), |
294 delete_on_destroy_(true), | 294 delete_on_destroy_(true), |
295 transparent_(false), | 295 transparent_(false), |
296 ignore_events_(false), | 296 ignore_events_(false), |
297 ignore_drag_leave_(false), | 297 ignore_drag_leave_(false), |
298 opacity_(255), | 298 opacity_(255), |
299 drag_data_(NULL), | 299 drag_data_(NULL), |
300 is_active_(false), | 300 is_active_(false), |
301 transient_to_parent_(false), | 301 transient_to_parent_(false), |
302 got_initial_focus_in_(false), | 302 got_initial_focus_in_(false), |
303 has_focus_(false), | 303 has_focus_(false), |
| 304 focus_on_creation_(true), |
304 always_on_top_(false), | 305 always_on_top_(false), |
305 is_double_buffered_(false), | 306 is_double_buffered_(false), |
306 should_handle_menu_key_release_(false), | 307 should_handle_menu_key_release_(false), |
307 dragged_view_(NULL), | 308 dragged_view_(NULL), |
308 painted_(false) { | 309 painted_(false) { |
309 #if defined(TOUCH_UI) && defined(HAVE_XINPUT2) | 310 #if defined(TOUCH_UI) && defined(HAVE_XINPUT2) |
310 // Make sure the touch factory is initialized so that it can setup XInput2 for | 311 // Make sure the touch factory is initialized so that it can setup XInput2 for |
311 // the widget. | 312 // the widget. |
312 TouchFactory::GetInstance(); | 313 TouchFactory::GetInstance(); |
313 #endif | 314 #endif |
314 set_native_widget(this); | |
315 static bool installed_message_loop_observer = false; | 315 static bool installed_message_loop_observer = false; |
316 if (!installed_message_loop_observer) { | 316 if (!installed_message_loop_observer) { |
317 installed_message_loop_observer = true; | 317 installed_message_loop_observer = true; |
318 MessageLoopForUI* loop = MessageLoopForUI::current(); | 318 MessageLoopForUI* loop = MessageLoopForUI::current(); |
319 if (loop) | 319 if (loop) |
320 loop->AddObserver(DropObserver::GetInstance()); | 320 loop->AddObserver(DropObserver::GetInstance()); |
321 } | 321 } |
322 } | 322 } |
323 | 323 |
324 WidgetGtk::~WidgetGtk() { | 324 WidgetGtk::~WidgetGtk() { |
325 // We need to delete the input method before calling DestroyRootView(), | 325 // We need to delete the input method before calling DestroyRootView(), |
326 // because it'll set focus_manager_ to NULL. | 326 // because it'll set focus_manager_ to NULL. |
327 input_method_.reset(); | 327 input_method_.reset(); |
328 DestroyRootView(); | |
329 DCHECK(delete_on_destroy_ || widget_ == NULL); | 328 DCHECK(delete_on_destroy_ || widget_ == NULL); |
| 329 if (delete_on_destroy_) |
| 330 delete delegate_; |
330 } | 331 } |
331 | 332 |
332 GtkWindow* WidgetGtk::GetTransientParent() const { | 333 GtkWindow* WidgetGtk::GetTransientParent() const { |
333 return (!child_ && widget_) ? | 334 return (!child_ && widget_) ? |
334 gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL; | 335 gtk_window_get_transient_for(GTK_WINDOW(widget_)) : NULL; |
335 } | 336 } |
336 | 337 |
337 bool WidgetGtk::MakeTransparent() { | 338 bool WidgetGtk::MakeTransparent() { |
338 // Transparency can only be enabled only if we haven't realized the widget. | 339 // Transparency can only be enabled only if we haven't realized the widget. |
339 DCHECK(!widget_); | 340 DCHECK(!widget_); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 437 |
437 drag_data_ = NULL; | 438 drag_data_ = NULL; |
438 | 439 |
439 if (drag_icon_widget) { | 440 if (drag_icon_widget) { |
440 gtk_widget_destroy(drag_icon_widget); | 441 gtk_widget_destroy(drag_icon_widget); |
441 g_object_unref(provider.drag_image()); | 442 g_object_unref(provider.drag_image()); |
442 } | 443 } |
443 } | 444 } |
444 | 445 |
445 void WidgetGtk::IsActiveChanged() { | 446 void WidgetGtk::IsActiveChanged() { |
446 WidgetDelegate* d = widget_delegate(); | 447 WidgetDelegate* d = GetWidget()->widget_delegate(); |
447 if (d) { | 448 if (d) { |
448 bool a = IsActive(); | 449 bool a = IsActive(); |
449 d->OnWidgetActivated(a); | 450 d->OnWidgetActivated(a); |
450 } | 451 } |
451 } | 452 } |
452 | 453 |
453 void WidgetGtk::SetInitialFocus() { | 454 void WidgetGtk::SetInitialFocus() { |
454 View* v = widget_delegate() ? | 455 if (!focus_on_creation_) |
455 widget_delegate()->GetInitiallyFocusedView() : NULL; | 456 return; |
| 457 |
| 458 View* v = GetWidget()->widget_delegate() ? |
| 459 GetWidget()->widget_delegate()->GetInitiallyFocusedView() : NULL; |
456 if (v) | 460 if (v) |
457 v->RequestFocus(); | 461 v->RequestFocus(); |
458 } | 462 } |
459 | 463 |
460 void WidgetGtk::ResetDropTarget() { | 464 void WidgetGtk::ResetDropTarget() { |
461 ignore_drag_leave_ = false; | 465 ignore_drag_leave_ = false; |
462 drop_target_.reset(NULL); | 466 drop_target_.reset(NULL); |
463 } | 467 } |
464 | 468 |
465 void WidgetGtk::GetRequestedSize(gfx::Size* out) const { | 469 void WidgetGtk::GetRequestedSize(gfx::Size* out) const { |
(...skipping 23 matching lines...) Expand all Loading... |
489 gpointer data = NULL; | 493 gpointer data = NULL; |
490 gdk_window_get_user_data(active_window, &data); | 494 gdk_window_get_user_data(active_window, &data); |
491 GtkWidget* widget = reinterpret_cast<GtkWidget*>(data); | 495 GtkWidget* widget = reinterpret_cast<GtkWidget*>(data); |
492 is_active_ = | 496 is_active_ = |
493 (widget && GTK_IS_WINDOW(widget) && | 497 (widget && GTK_IS_WINDOW(widget) && |
494 gtk_window_get_transient_for(GTK_WINDOW(widget)) == GTK_WINDOW( | 498 gtk_window_get_transient_for(GTK_WINDOW(widget)) == GTK_WINDOW( |
495 widget_)); | 499 widget_)); |
496 } | 500 } |
497 if (was_active != IsActive()) { | 501 if (was_active != IsActive()) { |
498 IsActiveChanged(); | 502 IsActiveChanged(); |
499 GetRootView()->SchedulePaint(); | 503 GetWidget()->GetRootView()->SchedulePaint(); |
500 } | 504 } |
501 } | 505 } |
502 | 506 |
503 //////////////////////////////////////////////////////////////////////////////// | 507 //////////////////////////////////////////////////////////////////////////////// |
504 // WidgetGtk, Widget implementation: | 508 // WidgetGtk, Widget implementation: |
505 | 509 |
506 gfx::NativeView WidgetGtk::GetNativeView() const { | |
507 return widget_; | |
508 } | |
509 | |
510 gfx::NativeWindow WidgetGtk::GetNativeWindow() const { | |
511 return child_ ? NULL : GTK_WINDOW(widget_); | |
512 } | |
513 | |
514 bool WidgetGtk::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { | |
515 NOTIMPLEMENTED(); | |
516 return false; | |
517 } | |
518 | |
519 Window* WidgetGtk::GetWindow() { | |
520 return GetWindowImpl(widget_); | |
521 } | |
522 | |
523 const Window* WidgetGtk::GetWindow() const { | |
524 return GetWindowImpl(widget_); | |
525 } | |
526 | |
527 void WidgetGtk::ViewHierarchyChanged(bool is_add, View* parent, View* child) { | |
528 Widget::ViewHierarchyChanged(is_add, parent, child); | |
529 if (drop_target_.get()) | |
530 drop_target_->ResetTargetViewIfEquals(child); | |
531 } | |
532 | |
533 void WidgetGtk::NotifyAccessibilityEvent( | |
534 View* view, | |
535 ui::AccessibilityTypes::Event event_type, | |
536 bool send_native_event) { | |
537 // Send the notification to the delegate. | |
538 if (ViewsDelegate::views_delegate) | |
539 ViewsDelegate::views_delegate->NotifyAccessibilityEvent(view, event_type); | |
540 | |
541 // In the future if we add native GTK accessibility support, the | |
542 // notification should be sent here. | |
543 } | |
544 | |
545 void WidgetGtk::ClearNativeFocus() { | 510 void WidgetGtk::ClearNativeFocus() { |
546 DCHECK(!child_); | 511 DCHECK(!child_); |
547 if (!GetNativeView()) { | 512 if (!GetNativeView()) { |
548 NOTREACHED(); | 513 NOTREACHED(); |
549 return; | 514 return; |
550 } | 515 } |
551 gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL); | 516 gtk_window_set_focus(GTK_WINDOW(GetNativeView()), NULL); |
552 } | 517 } |
553 | 518 |
554 bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { | 519 bool WidgetGtk::HandleKeyboardEvent(const KeyEvent& key) { |
555 if (!GetFocusManager()) | 520 if (!GetWidget()->GetFocusManager()) |
556 return false; | 521 return false; |
557 | 522 |
558 const int key_code = key.key_code(); | 523 const int key_code = key.key_code(); |
559 bool handled = false; | 524 bool handled = false; |
560 | 525 |
561 // Always reset |should_handle_menu_key_release_| unless we are handling a | 526 // Always reset |should_handle_menu_key_release_| unless we are handling a |
562 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only | 527 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only |
563 // be activated when handling a VKEY_MENU key release event which is preceded | 528 // be activated when handling a VKEY_MENU key release event which is preceded |
564 // by an un-handled VKEY_MENU key press event. | 529 // by an un-handled VKEY_MENU key press event. |
565 if (key_code != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED) | 530 if (key_code != ui::VKEY_MENU || key.type() != ui::ET_KEY_RELEASED) |
566 should_handle_menu_key_release_ = false; | 531 should_handle_menu_key_release_ = false; |
567 | 532 |
568 if (key.type() == ui::ET_KEY_PRESSED) { | 533 if (key.type() == ui::ET_KEY_PRESSED) { |
569 // VKEY_MENU is triggered by key release event. | 534 // VKEY_MENU is triggered by key release event. |
570 // FocusManager::OnKeyEvent() returns false when the key has been consumed. | 535 // FocusManager::OnKeyEvent() returns false when the key has been consumed. |
571 if (key_code != ui::VKEY_MENU) | 536 if (key_code != ui::VKEY_MENU) |
572 handled = !GetFocusManager()->OnKeyEvent(key); | 537 handled = !GetWidget()->GetFocusManager()->OnKeyEvent(key); |
573 else | 538 else |
574 should_handle_menu_key_release_ = true; | 539 should_handle_menu_key_release_ = true; |
575 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && | 540 } else if (key_code == ui::VKEY_MENU && should_handle_menu_key_release_ && |
576 (key.flags() & ~ui::EF_ALT_DOWN) == 0) { | 541 (key.flags() & ~ui::EF_ALT_DOWN) == 0) { |
577 // Trigger VKEY_MENU when only this key is pressed and released, and both | 542 // Trigger VKEY_MENU when only this key is pressed and released, and both |
578 // press and release events are not handled by others. | 543 // press and release events are not handled by others. |
579 Accelerator accelerator(ui::VKEY_MENU, false, false, false); | 544 Accelerator accelerator(ui::VKEY_MENU, false, false, false); |
580 handled = GetFocusManager()->ProcessAccelerator(accelerator); | 545 handled = GetWidget()->GetFocusManager()->ProcessAccelerator(accelerator); |
581 } | 546 } |
582 | 547 |
583 return handled; | 548 return handled; |
584 } | 549 } |
585 | 550 |
586 // static | 551 // static |
587 void WidgetGtk::EnableDebugPaint() { | 552 void WidgetGtk::EnableDebugPaint() { |
588 debug_paint_enabled_ = true; | 553 debug_paint_enabled_ = true; |
589 } | 554 } |
590 | 555 |
(...skipping 28 matching lines...) Expand all Loading... |
619 RemoveExposeHandlerIfExists(child); | 584 RemoveExposeHandlerIfExists(child); |
620 gulong id = g_signal_connect_after(child, "expose-event", | 585 gulong id = g_signal_connect_after(child, "expose-event", |
621 G_CALLBACK(&ChildExposeHandler), NULL); | 586 G_CALLBACK(&ChildExposeHandler), NULL); |
622 g_object_set_data(G_OBJECT(child), kExposeHandlerIdKey, | 587 g_object_set_data(G_OBJECT(child), kExposeHandlerIdKey, |
623 reinterpret_cast<void*>(id)); | 588 reinterpret_cast<void*>(id)); |
624 } | 589 } |
625 | 590 |
626 //////////////////////////////////////////////////////////////////////////////// | 591 //////////////////////////////////////////////////////////////////////////////// |
627 // WidgetGtk, NativeWidget implementation: | 592 // WidgetGtk, NativeWidget implementation: |
628 | 593 |
629 void WidgetGtk::InitNativeWidget(const InitParams& params) { | 594 void WidgetGtk::InitNativeWidget(const Widget::InitParams& params) { |
630 SetInitParams(params); | 595 SetInitParams(params); |
631 | 596 |
632 InitParams modified_params = params; | 597 Widget::InitParams modified_params = params; |
633 gfx::NativeView parent = params.parent; | 598 gfx::NativeView parent = params.parent; |
634 if (params.parent_widget) { | 599 if (params.parent_widget) { |
635 WidgetGtk* parent_gtk = | 600 WidgetGtk* parent_gtk = |
636 static_cast<WidgetGtk*>(params.parent_widget->native_widget()); | 601 static_cast<WidgetGtk*>(params.parent_widget->native_widget()); |
637 modified_params.parent = child_ ? parent_gtk->window_contents() | 602 modified_params.parent = child_ ? parent_gtk->window_contents() |
638 : params.parent_widget->GetNativeView(); | 603 : params.parent_widget->GetNativeView(); |
639 } | 604 } |
640 | 605 |
641 if (!child_) | 606 if (!child_) |
642 ActiveWindowWatcherX::AddObserver(this); | 607 ActiveWindowWatcherX::AddObserver(this); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 SetBounds(params.bounds); | 724 SetBounds(params.bounds); |
760 } else { | 725 } else { |
761 if (params.bounds.width() > 0 && params.bounds.height() > 0) | 726 if (params.bounds.width() > 0 && params.bounds.height() > 0) |
762 gtk_window_resize(GTK_WINDOW(widget_), params.bounds.width(), | 727 gtk_window_resize(GTK_WINDOW(widget_), params.bounds.width(), |
763 params.bounds.height()); | 728 params.bounds.height()); |
764 gtk_window_move(GTK_WINDOW(widget_), params.bounds.x(), params.bounds.y()); | 729 gtk_window_move(GTK_WINDOW(widget_), params.bounds.x(), params.bounds.y()); |
765 } | 730 } |
766 } | 731 } |
767 | 732 |
768 Widget* WidgetGtk::GetWidget() { | 733 Widget* WidgetGtk::GetWidget() { |
769 return this; | 734 return delegate_->AsWidget(); |
| 735 } |
| 736 |
| 737 const Widget* WidgetGtk::GetWidget() const { |
| 738 return delegate_->AsWidget(); |
| 739 } |
| 740 |
| 741 gfx::NativeView WidgetGtk::GetNativeView() const { |
| 742 return widget_; |
| 743 } |
| 744 |
| 745 gfx::NativeWindow WidgetGtk::GetNativeWindow() const { |
| 746 return child_ ? NULL : GTK_WINDOW(widget_); |
| 747 } |
| 748 |
| 749 Window* WidgetGtk::GetContainingWindow() { |
| 750 return GetWindowImpl(widget_); |
| 751 } |
| 752 |
| 753 const Window* WidgetGtk::GetContainingWindow() const { |
| 754 return GetWindowImpl(widget_); |
| 755 } |
| 756 |
| 757 void WidgetGtk::ViewRemoved(View* view) { |
| 758 if (drop_target_.get()) |
| 759 drop_target_->ResetTargetViewIfEquals(view); |
770 } | 760 } |
771 | 761 |
772 void WidgetGtk::SetNativeWindowProperty(const char* name, void* value) { | 762 void WidgetGtk::SetNativeWindowProperty(const char* name, void* value) { |
773 g_object_set_data(G_OBJECT(widget_), name, value); | 763 g_object_set_data(G_OBJECT(widget_), name, value); |
774 } | 764 } |
775 | 765 |
776 void* WidgetGtk::GetNativeWindowProperty(const char* name) { | 766 void* WidgetGtk::GetNativeWindowProperty(const char* name) { |
777 return g_object_get_data(G_OBJECT(widget_), name); | 767 return g_object_get_data(G_OBJECT(widget_), name); |
778 } | 768 } |
779 | 769 |
780 TooltipManager* WidgetGtk::GetTooltipManager() const { | 770 TooltipManager* WidgetGtk::GetTooltipManager() const { |
781 return tooltip_manager_.get(); | 771 return tooltip_manager_.get(); |
782 } | 772 } |
783 | 773 |
784 bool WidgetGtk::IsScreenReaderActive() const { | 774 bool WidgetGtk::IsScreenReaderActive() const { |
785 return false; | 775 return false; |
786 } | 776 } |
787 | 777 |
| 778 void WidgetGtk::SendNativeAccessibilityEvent( |
| 779 View* view, |
| 780 ui::AccessibilityTypes::Event event_type) { |
| 781 // In the future if we add native GTK accessibility support, the |
| 782 // notification should be sent here. |
| 783 } |
| 784 |
788 void WidgetGtk::SetMouseCapture() { | 785 void WidgetGtk::SetMouseCapture() { |
789 DCHECK(!HasMouseCapture()); | 786 DCHECK(!HasMouseCapture()); |
790 gtk_grab_add(window_contents_); | 787 gtk_grab_add(window_contents_); |
791 } | 788 } |
792 | 789 |
793 void WidgetGtk::ReleaseMouseCapture() { | 790 void WidgetGtk::ReleaseMouseCapture() { |
794 if (HasMouseCapture()) | 791 if (HasMouseCapture()) |
795 gtk_grab_remove(window_contents_); | 792 gtk_grab_remove(window_contents_); |
796 } | 793 } |
797 | 794 |
798 bool WidgetGtk::HasMouseCapture() const { | 795 bool WidgetGtk::HasMouseCapture() const { |
799 // TODO(beng): Should be able to use gtk_widget_has_grab() here but the | 796 // TODO(beng): Should be able to use gtk_widget_has_grab() here but the |
800 // trybots don't have Gtk 2.18. | 797 // trybots don't have Gtk 2.18. |
801 return GTK_WIDGET_HAS_GRAB(window_contents_); | 798 return GTK_WIDGET_HAS_GRAB(window_contents_); |
802 } | 799 } |
803 | 800 |
| 801 bool WidgetGtk::IsMouseButtonDown() const { |
| 802 bool button_pressed = false; |
| 803 GdkEvent* event = gtk_get_current_event(); |
| 804 if (event) { |
| 805 button_pressed = event->type == GDK_BUTTON_PRESS || |
| 806 event->type == GDK_2BUTTON_PRESS || |
| 807 event->type == GDK_3BUTTON_PRESS; |
| 808 gdk_event_free(event); |
| 809 } |
| 810 return button_pressed; |
| 811 } |
| 812 |
804 InputMethod* WidgetGtk::GetInputMethodNative() { | 813 InputMethod* WidgetGtk::GetInputMethodNative() { |
805 return input_method_.get(); | 814 return input_method_.get(); |
806 } | 815 } |
807 | 816 |
808 void WidgetGtk::ReplaceInputMethod(InputMethod* input_method) { | 817 void WidgetGtk::ReplaceInputMethod(InputMethod* input_method) { |
809 input_method_.reset(input_method); | 818 input_method_.reset(input_method); |
810 if (input_method) { | 819 if (input_method) { |
811 input_method->set_delegate(this); | 820 input_method->set_delegate(this); |
812 input_method->Init(GetWidget()); | 821 input_method->Init(GetWidget()); |
813 } | 822 } |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 | 1020 |
1012 //////////////////////////////////////////////////////////////////////////////// | 1021 //////////////////////////////////////////////////////////////////////////////// |
1013 // WidgetGtk, protected: | 1022 // WidgetGtk, protected: |
1014 | 1023 |
1015 void WidgetGtk::OnSizeRequest(GtkWidget* widget, GtkRequisition* requisition) { | 1024 void WidgetGtk::OnSizeRequest(GtkWidget* widget, GtkRequisition* requisition) { |
1016 // Do only return the preferred size for child windows. GtkWindow interprets | 1025 // Do only return the preferred size for child windows. GtkWindow interprets |
1017 // the requisition as a minimum size for top level windows, returning a | 1026 // the requisition as a minimum size for top level windows, returning a |
1018 // preferred size for these would prevents us from setting smaller window | 1027 // preferred size for these would prevents us from setting smaller window |
1019 // sizes. | 1028 // sizes. |
1020 if (child_) { | 1029 if (child_) { |
1021 gfx::Size size(GetRootView()->GetPreferredSize()); | 1030 gfx::Size size(GetWidget()->GetRootView()->GetPreferredSize()); |
1022 requisition->width = size.width(); | 1031 requisition->width = size.width(); |
1023 requisition->height = size.height(); | 1032 requisition->height = size.height(); |
1024 } | 1033 } |
1025 } | 1034 } |
1026 | 1035 |
1027 void WidgetGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { | 1036 void WidgetGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { |
1028 // See comment next to size_ as to why we do this. Also note, it's tempting | 1037 // See comment next to size_ as to why we do this. Also note, it's tempting |
1029 // to put this in the static method so subclasses don't need to worry about | 1038 // to put this in the static method so subclasses don't need to worry about |
1030 // it, but if a subclasses needs to set a shape then they need to always | 1039 // it, but if a subclasses needs to set a shape then they need to always |
1031 // reset the shape in this method regardless of whether the size changed. | 1040 // reset the shape in this method regardless of whether the size changed. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 drop_target_.reset(NULL); | 1155 drop_target_.reset(NULL); |
1147 } | 1156 } |
1148 } | 1157 } |
1149 | 1158 |
1150 gboolean WidgetGtk::OnDragMotion(GtkWidget* widget, | 1159 gboolean WidgetGtk::OnDragMotion(GtkWidget* widget, |
1151 GdkDragContext* context, | 1160 GdkDragContext* context, |
1152 gint x, | 1161 gint x, |
1153 gint y, | 1162 gint y, |
1154 guint time) { | 1163 guint time) { |
1155 if (!drop_target_.get()) | 1164 if (!drop_target_.get()) |
1156 drop_target_.reset(new DropTargetGtk(GetRootView(), context)); | 1165 drop_target_.reset(new DropTargetGtk(GetWidget()->GetRootView(), context)); |
1157 return drop_target_->OnDragMotion(context, x, y, time); | 1166 return drop_target_->OnDragMotion(context, x, y, time); |
1158 } | 1167 } |
1159 | 1168 |
1160 gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { | 1169 gboolean WidgetGtk::OnEnterNotify(GtkWidget* widget, GdkEventCrossing* event) { |
1161 if (HasMouseCapture() && event->mode == GDK_CROSSING_GRAB) { | 1170 if (HasMouseCapture() && event->mode == GDK_CROSSING_GRAB) { |
1162 // Doing a grab results an async enter event, regardless of where the mouse | 1171 // Doing a grab results an async enter event, regardless of where the mouse |
1163 // is. We don't want to generate a mouse move in this case. | 1172 // is. We don't want to generate a mouse move in this case. |
1164 return false; | 1173 return false; |
1165 } | 1174 } |
1166 | 1175 |
1167 if (!last_mouse_event_was_move_ && !is_mouse_button_pressed_) { | 1176 if (!GetWidget()->last_mouse_event_was_move_ && |
| 1177 !GetWidget()->is_mouse_button_pressed_) { |
1168 // When a mouse button is pressed gtk generates a leave, enter, press. | 1178 // When a mouse button is pressed gtk generates a leave, enter, press. |
1169 // RootView expects to get a mouse move before a press, otherwise enter is | 1179 // RootView expects to get a mouse move before a press, otherwise enter is |
1170 // not set. So we generate a move here. | 1180 // not set. So we generate a move here. |
1171 GdkEventMotion motion = { GDK_MOTION_NOTIFY, event->window, | 1181 GdkEventMotion motion = { GDK_MOTION_NOTIFY, event->window, |
1172 event->send_event, event->time, event->x, event->y, NULL, event->state, | 1182 event->send_event, event->time, event->x, event->y, NULL, event->state, |
1173 0, NULL, event->x_root, event->y_root }; | 1183 0, NULL, event->x_root, event->y_root }; |
1174 | 1184 |
1175 // If this event is the result of pressing a button then one of the button | 1185 // If this event is the result of pressing a button then one of the button |
1176 // modifiers is set. Unset it as we're compensating for the leave generated | 1186 // modifiers is set. Unset it as we're compensating for the leave generated |
1177 // when you press a button. | 1187 // when you press a button. |
1178 motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); | 1188 motion.state &= ~(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK); |
1179 | 1189 |
1180 MouseEvent mouse_event(TransformEvent(&motion)); | 1190 MouseEvent mouse_event(TransformEvent(&motion)); |
1181 delegate_->OnMouseEvent(mouse_event); | 1191 delegate_->OnMouseEvent(mouse_event); |
1182 } | 1192 } |
1183 | |
1184 return false; | 1193 return false; |
1185 } | 1194 } |
1186 | 1195 |
1187 gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { | 1196 gboolean WidgetGtk::OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { |
1188 last_mouse_event_was_move_ = false; | 1197 GetWidget()->ResetLastMouseMoveFlag(); |
1189 if (!HasMouseCapture() && !is_mouse_button_pressed_) { | 1198 |
| 1199 if (!HasMouseCapture() && !GetWidget()->is_mouse_button_pressed_) { |
1190 MouseEvent mouse_event(TransformEvent(event)); | 1200 MouseEvent mouse_event(TransformEvent(event)); |
1191 delegate_->OnMouseEvent(mouse_event); | 1201 delegate_->OnMouseEvent(mouse_event); |
1192 } | 1202 } |
1193 return false; | 1203 return false; |
1194 } | 1204 } |
1195 | 1205 |
1196 gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { | 1206 gboolean WidgetGtk::OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { |
1197 MouseEvent mouse_event(TransformEvent(event)); | 1207 MouseEvent mouse_event(TransformEvent(event)); |
1198 delegate_->OnMouseEvent(mouse_event); | 1208 delegate_->OnMouseEvent(mouse_event); |
1199 return true; | 1209 return true; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 void WidgetGtk::HandleXGrabBroke() { | 1349 void WidgetGtk::HandleXGrabBroke() { |
1340 } | 1350 } |
1341 | 1351 |
1342 void WidgetGtk::HandleGtkGrabBroke() { | 1352 void WidgetGtk::HandleGtkGrabBroke() { |
1343 delegate_->OnMouseCaptureLost(); | 1353 delegate_->OnMouseCaptureLost(); |
1344 } | 1354 } |
1345 | 1355 |
1346 //////////////////////////////////////////////////////////////////////////////// | 1356 //////////////////////////////////////////////////////////////////////////////// |
1347 // WidgetGtk, private: | 1357 // WidgetGtk, private: |
1348 | 1358 |
1349 RootView* WidgetGtk::CreateRootView() { | |
1350 return new RootView(this); | |
1351 } | |
1352 | |
1353 gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { | 1359 gfx::AcceleratedWidget WidgetGtk::GetAcceleratedWidget() { |
1354 DCHECK(window_contents_ && window_contents_->window); | 1360 DCHECK(window_contents_ && window_contents_->window); |
1355 return GDK_WINDOW_XID(window_contents_->window); | 1361 return GDK_WINDOW_XID(window_contents_->window); |
1356 } | 1362 } |
1357 | 1363 |
1358 void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { | 1364 void WidgetGtk::DispatchKeyEventPostIME(const KeyEvent& key) { |
1359 // Always reset |should_handle_menu_key_release_| unless we are handling a | 1365 // Always reset |should_handle_menu_key_release_| unless we are handling a |
1360 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only | 1366 // VKEY_MENU key release event. It ensures that VKEY_MENU accelerator can only |
1361 // be activated when handling a VKEY_MENU key release event which is preceded | 1367 // be activated when handling a VKEY_MENU key release event which is preceded |
1362 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent(). | 1368 // by an unhandled VKEY_MENU key press event. See also HandleKeyboardEvent(). |
(...skipping 22 matching lines...) Expand all Loading... |
1385 // always consumes the key event and send it back to us later by calling | 1391 // always consumes the key event and send it back to us later by calling |
1386 // HandleKeyboardEvent() directly, if it's not handled by webkit. | 1392 // HandleKeyboardEvent() directly, if it's not handled by webkit. |
1387 if (!handled) | 1393 if (!handled) |
1388 handled = HandleKeyboardEvent(key); | 1394 handled = HandleKeyboardEvent(key); |
1389 | 1395 |
1390 // Dispatch the key event for bindings processing. | 1396 // Dispatch the key event for bindings processing. |
1391 if (!handled && event && GTK_IS_WINDOW(widget_)) | 1397 if (!handled && event && GTK_IS_WINDOW(widget_)) |
1392 gtk_bindings_activate_event(GTK_OBJECT(widget_), event); | 1398 gtk_bindings_activate_event(GTK_OBJECT(widget_), event); |
1393 } | 1399 } |
1394 | 1400 |
1395 void WidgetGtk::SetInitParams(const InitParams& params) { | 1401 void WidgetGtk::SetInitParams(const Widget::InitParams& params) { |
1396 DCHECK(!GetNativeView()); | 1402 DCHECK(!GetNativeView()); |
1397 | 1403 |
1398 delete_on_destroy_ = params.delete_on_destroy; | 1404 delete_on_destroy_ = params.delete_on_destroy; |
1399 child_ = params.child; | 1405 child_ = params.child; |
1400 | 1406 |
| 1407 // TODO(beng): The secondary checks here actually obviate the need for |
| 1408 // params.transient but that's only because WidgetGtk considers |
| 1409 // any top-level widget to be a transient widget. We will probably |
| 1410 // want to ammend this assumption at some point. |
| 1411 if (params.transient || params.parent || params.parent_widget) |
| 1412 transient_to_parent_ = true; |
1401 if (params.transparent) | 1413 if (params.transparent) |
1402 MakeTransparent(); | 1414 MakeTransparent(); |
1403 if (!params.accept_events && !child_) | 1415 if (!params.accept_events && !child_) |
1404 ignore_events_ = true; | 1416 ignore_events_ = true; |
1405 if (params.double_buffer) | 1417 if (params.double_buffer) |
1406 EnableDoubleBuffer(true); | 1418 EnableDoubleBuffer(true); |
1407 | |
1408 if (params.type == InitParams::TYPE_MENU) { | |
1409 GdkEvent* event = gtk_get_current_event(); | |
1410 if (event) { | |
1411 is_mouse_button_pressed_ = event->type == GDK_BUTTON_PRESS || | |
1412 event->type == GDK_2BUTTON_PRESS || | |
1413 event->type == GDK_3BUTTON_PRESS; | |
1414 gdk_event_free(event); | |
1415 } | |
1416 } | |
1417 } | 1419 } |
1418 | 1420 |
1419 gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { | 1421 gboolean WidgetGtk::OnWindowPaint(GtkWidget* widget, GdkEventExpose* event) { |
1420 // Clear the background to be totally transparent. We don't need to | 1422 // Clear the background to be totally transparent. We don't need to |
1421 // paint the root view here as that is done by OnPaint. | 1423 // paint the root view here as that is done by OnPaint. |
1422 DCHECK(transparent_); | 1424 DCHECK(transparent_); |
1423 DrawTransparentBackground(widget, event); | 1425 DrawTransparentBackground(widget, event); |
1424 // The Keyboard layout view has a renderer that covers the entire | 1426 // The Keyboard layout view has a renderer that covers the entire |
1425 // window, which prevents OnPaint from being called on window_contents_, | 1427 // window, which prevents OnPaint from being called on window_contents_, |
1426 // so we need to remove the FREEZE_UPDATES property here. | 1428 // so we need to remove the FREEZE_UPDATES property here. |
(...skipping 26 matching lines...) Expand all Loading... |
1453 return false; | 1455 return false; |
1454 } | 1456 } |
1455 | 1457 |
1456 // static | 1458 // static |
1457 Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { | 1459 Window* WidgetGtk::GetWindowImpl(GtkWidget* widget) { |
1458 GtkWidget* parent = widget; | 1460 GtkWidget* parent = widget; |
1459 while (parent) { | 1461 while (parent) { |
1460 WidgetGtk* widget_gtk = static_cast<WidgetGtk*>( | 1462 WidgetGtk* widget_gtk = static_cast<WidgetGtk*>( |
1461 NativeWidget::GetNativeWidgetForNativeView(parent)); | 1463 NativeWidget::GetNativeWidgetForNativeView(parent)); |
1462 if (widget_gtk && widget_gtk->is_window_) | 1464 if (widget_gtk && widget_gtk->is_window_) |
1463 return static_cast<WindowGtk*>(widget_gtk); | 1465 return static_cast<WindowGtk*>(widget_gtk)->GetWindow(); |
1464 parent = gtk_widget_get_parent(parent); | 1466 parent = gtk_widget_get_parent(parent); |
1465 } | 1467 } |
1466 return NULL; | 1468 return NULL; |
1467 } | 1469 } |
1468 | 1470 |
1469 void WidgetGtk::CreateGtkWidget(const InitParams& params) { | 1471 void WidgetGtk::CreateGtkWidget(const Widget::InitParams& params) { |
1470 // We turn off double buffering for two reasons: | 1472 // We turn off double buffering for two reasons: |
1471 // 1. We draw to a canvas then composite to the screen, which means we're | 1473 // 1. We draw to a canvas then composite to the screen, which means we're |
1472 // doing our own double buffering already. | 1474 // doing our own double buffering already. |
1473 // 2. GTKs double buffering clips to the dirty region. RootView occasionally | 1475 // 2. GTKs double buffering clips to the dirty region. RootView occasionally |
1474 // needs to expand the paint region (see RootView::OnPaint). This means | 1476 // needs to expand the paint region (see RootView::OnPaint). This means |
1475 // that if we use GTK's double buffering and we tried to expand the dirty | 1477 // that if we use GTK's double buffering and we tried to expand the dirty |
1476 // region, it wouldn't get painted. | 1478 // region, it wouldn't get painted. |
1477 if (child_) { | 1479 if (child_) { |
1478 window_contents_ = widget_ = gtk_views_fixed_new(); | 1480 window_contents_ = widget_ = gtk_views_fixed_new(); |
1479 gtk_widget_set_name(widget_, "views-gtkwidget-child-fixed"); | 1481 gtk_widget_set_name(widget_, "views-gtkwidget-child-fixed"); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 // This can't be done without a parent present, or stale data | 1515 // This can't be done without a parent present, or stale data |
1514 // might show up on the screen as seen in | 1516 // might show up on the screen as seen in |
1515 // http://code.google.com/p/chromium/issues/detail?id=53870 | 1517 // http://code.google.com/p/chromium/issues/detail?id=53870 |
1516 GtkAllocation alloc = | 1518 GtkAllocation alloc = |
1517 { 0, 0, params.bounds.width(), params.bounds.height() }; | 1519 { 0, 0, params.bounds.width(), params.bounds.height() }; |
1518 gtk_widget_size_allocate(widget_, &alloc); | 1520 gtk_widget_size_allocate(widget_, &alloc); |
1519 } | 1521 } |
1520 } else { | 1522 } else { |
1521 // Use our own window class to override GtkWindow's move_focus method. | 1523 // Use our own window class to override GtkWindow's move_focus method. |
1522 widget_ = gtk_views_window_new( | 1524 widget_ = gtk_views_window_new( |
1523 params.type == InitParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL | 1525 params.type == Widget::InitParams::TYPE_WINDOW ? GTK_WINDOW_TOPLEVEL |
1524 : GTK_WINDOW_POPUP); | 1526 : GTK_WINDOW_POPUP); |
1525 gtk_widget_set_name(widget_, "views-gtkwidget-window"); | 1527 gtk_widget_set_name(widget_, "views-gtkwidget-window"); |
1526 if (transient_to_parent_) { | 1528 if (transient_to_parent_) { |
1527 gtk_window_set_transient_for(GTK_WINDOW(widget_), | 1529 gtk_window_set_transient_for(GTK_WINDOW(widget_), |
1528 GTK_WINDOW(params.parent)); | 1530 GTK_WINDOW(params.parent)); |
1529 } | 1531 } |
1530 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); | 1532 GTK_WIDGET_UNSET_FLAGS(widget_, GTK_DOUBLE_BUFFERED); |
1531 | 1533 |
1532 // Gtk determines the size for windows based on the requested size of the | 1534 // Gtk determines the size for windows based on the requested size of the |
1533 // child. For WidgetGtk the child is a fixed. If the fixed ends up with a | 1535 // child. For WidgetGtk the child is a fixed. If the fixed ends up with a |
1534 // child widget it's possible the child widget will drive the requested size | 1536 // child widget it's possible the child widget will drive the requested size |
(...skipping 18 matching lines...) Expand all Loading... |
1553 gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); | 1555 gtk_window_set_position(GTK_WINDOW(widget_), GTK_WIN_POS_NONE); |
1554 | 1556 |
1555 window_contents_ = gtk_views_fixed_new(); | 1557 window_contents_ = gtk_views_fixed_new(); |
1556 gtk_widget_set_name(window_contents_, "views-gtkwidget-window-fixed"); | 1558 gtk_widget_set_name(window_contents_, "views-gtkwidget-window-fixed"); |
1557 if (!is_double_buffered_) | 1559 if (!is_double_buffered_) |
1558 GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); | 1560 GTK_WIDGET_UNSET_FLAGS(window_contents_, GTK_DOUBLE_BUFFERED); |
1559 gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); | 1561 gtk_fixed_set_has_window(GTK_FIXED(window_contents_), true); |
1560 gtk_container_add(GTK_CONTAINER(widget_), window_contents_); | 1562 gtk_container_add(GTK_CONTAINER(widget_), window_contents_); |
1561 gtk_widget_show(window_contents_); | 1563 gtk_widget_show(window_contents_); |
1562 g_object_set_data(G_OBJECT(window_contents_), kNativeWidgetKey, | 1564 g_object_set_data(G_OBJECT(window_contents_), kNativeWidgetKey, |
1563 static_cast<Widget*>(this)); | 1565 static_cast<WidgetGtk*>(this)); |
1564 if (transparent_) | 1566 if (transparent_) |
1565 ConfigureWidgetForTransparentBackground(NULL); | 1567 ConfigureWidgetForTransparentBackground(NULL); |
1566 | 1568 |
1567 if (ignore_events_) | 1569 if (ignore_events_) |
1568 ConfigureWidgetForIgnoreEvents(); | 1570 ConfigureWidgetForIgnoreEvents(); |
1569 | 1571 |
1570 // Realize the window_contents_ so that we can always get a handle for | 1572 // Realize the window_contents_ so that we can always get a handle for |
1571 // acceleration. Without this we need to check every time paint is | 1573 // acceleration. Without this we need to check every time paint is |
1572 // invoked. | 1574 // invoked. |
1573 gtk_widget_realize(window_contents_); | 1575 gtk_widget_realize(window_contents_); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); | 1638 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); |
1637 gdk_cairo_region(cr, event->region); | 1639 gdk_cairo_region(cr, event->region); |
1638 cairo_fill(cr); | 1640 cairo_fill(cr); |
1639 cairo_destroy(cr); | 1641 cairo_destroy(cr); |
1640 } | 1642 } |
1641 | 1643 |
1642 //////////////////////////////////////////////////////////////////////////////// | 1644 //////////////////////////////////////////////////////////////////////////////// |
1643 // Widget, public: | 1645 // Widget, public: |
1644 | 1646 |
1645 // static | 1647 // static |
1646 Widget* Widget::CreateWidget() { | |
1647 return new WidgetGtk(); | |
1648 } | |
1649 | |
1650 // static | |
1651 void Widget::NotifyLocaleChanged() { | 1648 void Widget::NotifyLocaleChanged() { |
1652 GList *window_list = gtk_window_list_toplevels(); | 1649 GList *window_list = gtk_window_list_toplevels(); |
1653 for (GList* element = window_list; element; element = g_list_next(element)) { | 1650 for (GList* element = window_list; element; element = g_list_next(element)) { |
1654 NativeWidget* native_widget = | 1651 NativeWidget* native_widget = |
1655 NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data)); | 1652 NativeWidget::GetNativeWidgetForNativeWindow(GTK_WINDOW(element->data)); |
1656 if (native_widget) | 1653 if (native_widget) |
1657 native_widget->GetWidget()->LocaleChanged(); | 1654 native_widget->GetWidget()->LocaleChanged(); |
1658 } | 1655 } |
1659 g_list_free(window_list); | 1656 g_list_free(window_list); |
1660 } | 1657 } |
1661 | 1658 |
1662 // static | 1659 // static |
| 1660 void Widget::CloseAllSecondaryWidgets() { |
| 1661 GList* windows = gtk_window_list_toplevels(); |
| 1662 for (GList* window = windows; window; |
| 1663 window = g_list_next(window)) { |
| 1664 NativeWidget* native_widget = NativeWidget::GetNativeWidgetForNativeView( |
| 1665 GTK_WIDGET(window->data)); |
| 1666 if (native_widget) { |
| 1667 Widget* widget = native_widget->GetWidget(); |
| 1668 if (widget->is_secondary_widget()) |
| 1669 widget->Close(); |
| 1670 } |
| 1671 } |
| 1672 g_list_free(windows); |
| 1673 } |
| 1674 |
| 1675 // static |
1663 bool Widget::ConvertRect(const Widget* source, | 1676 bool Widget::ConvertRect(const Widget* source, |
1664 const Widget* target, | 1677 const Widget* target, |
1665 gfx::Rect* rect) { | 1678 gfx::Rect* rect) { |
1666 DCHECK(source); | 1679 DCHECK(source); |
1667 DCHECK(target); | 1680 DCHECK(target); |
1668 DCHECK(rect); | 1681 DCHECK(rect); |
1669 | 1682 |
1670 GtkWidget* source_widget = source->GetNativeView(); | 1683 GtkWidget* source_widget = source->GetNativeView(); |
1671 GtkWidget* target_widget = target->GetNativeView(); | 1684 GtkWidget* target_widget = target->GetNativeView(); |
1672 if (source_widget == target_widget) | 1685 if (source_widget == target_widget) |
1673 return true; | 1686 return true; |
1674 | 1687 |
1675 if (!source_widget || !target_widget) | 1688 if (!source_widget || !target_widget) |
1676 return false; | 1689 return false; |
1677 | 1690 |
1678 GdkRectangle gdk_rect = rect->ToGdkRectangle(); | 1691 GdkRectangle gdk_rect = rect->ToGdkRectangle(); |
1679 if (gtk_widget_translate_coordinates(source_widget, target_widget, | 1692 if (gtk_widget_translate_coordinates(source_widget, target_widget, |
1680 gdk_rect.x, gdk_rect.y, | 1693 gdk_rect.x, gdk_rect.y, |
1681 &gdk_rect.x, &gdk_rect.y)) { | 1694 &gdk_rect.x, &gdk_rect.y)) { |
1682 *rect = gdk_rect; | 1695 *rect = gdk_rect; |
1683 return true; | 1696 return true; |
1684 } | 1697 } |
1685 return false; | 1698 return false; |
1686 } | 1699 } |
1687 | 1700 |
1688 //////////////////////////////////////////////////////////////////////////////// | 1701 //////////////////////////////////////////////////////////////////////////////// |
1689 // NativeWidget, public: | 1702 // NativeWidget, public: |
1690 | 1703 |
1691 // static | 1704 // static |
| 1705 NativeWidget* NativeWidget::CreateNativeWidget( |
| 1706 internal::NativeWidgetDelegate* delegate) { |
| 1707 return new WidgetGtk(delegate); |
| 1708 } |
| 1709 |
| 1710 // static |
1692 NativeWidget* NativeWidget::GetNativeWidgetForNativeView( | 1711 NativeWidget* NativeWidget::GetNativeWidgetForNativeView( |
1693 gfx::NativeView native_view) { | 1712 gfx::NativeView native_view) { |
1694 if (!native_view) | 1713 if (!native_view) |
1695 return NULL; | 1714 return NULL; |
1696 return reinterpret_cast<WidgetGtk*>( | 1715 return reinterpret_cast<WidgetGtk*>( |
1697 g_object_get_data(G_OBJECT(native_view), kNativeWidgetKey)); | 1716 g_object_get_data(G_OBJECT(native_view), kNativeWidgetKey)); |
1698 } | 1717 } |
1699 | 1718 |
1700 // static | 1719 // static |
1701 NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow( | 1720 NativeWidget* NativeWidget::GetNativeWidgetForNativeWindow( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 return; | 1752 return; |
1734 | 1753 |
1735 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); | 1754 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); |
1736 if (native_widget) | 1755 if (native_widget) |
1737 children->insert(native_widget); | 1756 children->insert(native_widget); |
1738 gtk_container_foreach(GTK_CONTAINER(native_view), | 1757 gtk_container_foreach(GTK_CONTAINER(native_view), |
1739 EnumerateChildWidgetsForNativeWidgets, | 1758 EnumerateChildWidgetsForNativeWidgets, |
1740 reinterpret_cast<gpointer>(children)); | 1759 reinterpret_cast<gpointer>(children)); |
1741 } | 1760 } |
1742 | 1761 |
| 1762 // static |
| 1763 void NativeWidget::ReparentNativeView(gfx::NativeView native_view, |
| 1764 gfx::NativeView new_parent) { |
| 1765 if (!native_view) |
| 1766 return; |
| 1767 |
| 1768 gfx::NativeView previous_parent = gtk_widget_get_parent(native_view); |
| 1769 if (previous_parent == new_parent) |
| 1770 return; |
| 1771 |
| 1772 NativeWidgets widgets; |
| 1773 GetAllNativeWidgets(native_view, &widgets); |
| 1774 |
| 1775 // First notify all the widgets that they are being disassociated |
| 1776 // from their previous parent. |
| 1777 for (NativeWidgets::iterator it = widgets.begin(); |
| 1778 it != widgets.end(); ++it) { |
| 1779 // TODO(beng): Rename this notification to NotifyNativeViewChanging() |
| 1780 // and eliminate the bool parameter. |
| 1781 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(false, |
| 1782 previous_parent); |
| 1783 } |
| 1784 |
| 1785 if (gtk_widget_get_parent(native_view)) |
| 1786 gtk_widget_reparent(native_view, new_parent); |
| 1787 else |
| 1788 gtk_container_add(GTK_CONTAINER(new_parent), native_view); |
| 1789 |
| 1790 // And now, notify them that they have a brand new parent. |
| 1791 for (NativeWidgets::iterator it = widgets.begin(); |
| 1792 it != widgets.end(); ++it) { |
| 1793 (*it)->GetWidget()->NotifyNativeViewHierarchyChanged(true, |
| 1794 new_parent); |
| 1795 } |
| 1796 } |
| 1797 |
1743 } // namespace views | 1798 } // namespace views |
OLD | NEW |