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 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 if (parent) { | 590 if (parent) { |
591 SetBounds(bounds); | 591 SetBounds(bounds); |
592 } | 592 } |
593 } else { | 593 } else { |
594 if (bounds.width() > 0 && bounds.height() > 0) | 594 if (bounds.width() > 0 && bounds.height() > 0) |
595 gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height()); | 595 gtk_window_resize(GTK_WINDOW(widget_), bounds.width(), bounds.height()); |
596 gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y()); | 596 gtk_window_move(GTK_WINDOW(widget_), bounds.x(), bounds.y()); |
597 } | 597 } |
598 } | 598 } |
599 | 599 |
600 void WidgetGtk::SetBounds(const gfx::Rect& bounds) { | |
601 if (type_ == TYPE_CHILD) { | |
602 GtkWidget* parent = gtk_widget_get_parent(widget_); | |
603 if (GTK_IS_VIEWS_FIXED(parent)) { | |
604 WidgetGtk* parent_widget = static_cast<WidgetGtk*>( | |
605 NativeWidget::GetNativeWidgetForNativeView(parent)); | |
606 parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), | |
607 bounds.width(), bounds.height()); | |
608 } else { | |
609 DCHECK(GTK_IS_FIXED(parent)) | |
610 << "Parent of WidgetGtk has to be Fixed or ViewsFixed"; | |
611 // Just request the size if the parent is not WidgetGtk but plain | |
612 // GtkFixed. WidgetGtk does not know the minimum size so we assume | |
613 // the caller of the SetBounds knows exactly how big it wants to be. | |
614 gtk_widget_set_size_request(widget_, bounds.width(), bounds.height()); | |
615 if (parent != null_parent_) | |
616 gtk_fixed_move(GTK_FIXED(parent), widget_, bounds.x(), bounds.y()); | |
617 } | |
618 } else { | |
619 if (GTK_WIDGET_MAPPED(widget_)) { | |
620 // If the widget is mapped (on screen), we can move and resize with one | |
621 // call, which avoids two separate window manager steps. | |
622 gdk_window_move_resize(widget_->window, bounds.x(), bounds.y(), | |
623 bounds.width(), bounds.height()); | |
624 } | |
625 | |
626 // Always call gtk_window_move and gtk_window_resize so that GtkWindow's | |
627 // geometry info is up-to-date. | |
628 GtkWindow* gtk_window = GTK_WINDOW(widget_); | |
629 // TODO: this may need to set an initial size if not showing. | |
630 // TODO: need to constrain based on screen size. | |
631 if (!bounds.IsEmpty()) { | |
632 gtk_window_resize(gtk_window, bounds.width(), bounds.height()); | |
633 } | |
634 gtk_window_move(gtk_window, bounds.x(), bounds.y()); | |
635 } | |
636 } | |
637 | |
638 void WidgetGtk::MoveAbove(Widget* widget) { | |
639 DCHECK(widget_); | |
640 DCHECK(widget_->window); | |
641 // TODO(oshima): gdk_window_restack is not available in gtk2.0, so | |
642 // we're simply raising the window to the top. We should switch to | |
643 // gdk_window_restack when we upgrade gtk to 2.18 or up. | |
644 gdk_window_raise(widget_->window); | |
645 } | |
646 | |
647 void WidgetGtk::SetShape(gfx::NativeRegion region) { | |
648 DCHECK(widget_); | |
649 DCHECK(widget_->window); | |
650 gdk_window_shape_combine_region(widget_->window, region, 0, 0); | |
651 gdk_region_destroy(region); | |
652 } | |
653 | |
654 void WidgetGtk::Close() { | |
655 if (!widget_) | |
656 return; // No need to do anything. | |
657 | |
658 // Hide first. | |
659 Hide(); | |
660 if (close_widget_factory_.empty()) { | |
661 // And we delay the close just in case we're on the stack. | |
662 MessageLoop::current()->PostTask(FROM_HERE, | |
663 close_widget_factory_.NewRunnableMethod( | |
664 &WidgetGtk::CloseNow)); | |
665 } | |
666 } | |
667 | |
668 void WidgetGtk::CloseNow() { | |
669 if (widget_) { | |
670 gtk_widget_destroy(widget_); // Triggers OnDestroy(). | |
671 } | |
672 } | |
673 | |
674 void WidgetGtk::Show() { | |
675 if (widget_) { | |
676 gtk_widget_show(widget_); | |
677 if (widget_->window) | |
678 gdk_window_raise(widget_->window); | |
679 } | |
680 } | |
681 | |
682 void WidgetGtk::Hide() { | |
683 if (widget_) { | |
684 gtk_widget_hide(widget_); | |
685 if (widget_->window) | |
686 gdk_window_lower(widget_->window); | |
687 } | |
688 } | |
689 | |
690 gfx::NativeView WidgetGtk::GetNativeView() const { | 600 gfx::NativeView WidgetGtk::GetNativeView() const { |
691 return widget_; | 601 return widget_; |
692 } | 602 } |
693 | 603 |
694 void WidgetGtk::SetOpacity(unsigned char opacity) { | |
695 opacity_ = opacity; | |
696 if (widget_) { | |
697 // We can only set the opacity when the widget has been realized. | |
698 gdk_window_set_opacity(widget_->window, static_cast<gdouble>(opacity) / | |
699 static_cast<gdouble>(255)); | |
700 } | |
701 } | |
702 | |
703 void WidgetGtk::SetAlwaysOnTop(bool on_top) { | |
704 DCHECK(type_ != TYPE_CHILD); | |
705 always_on_top_ = on_top; | |
706 if (widget_) | |
707 gtk_window_set_keep_above(GTK_WINDOW(widget_), on_top); | |
708 } | |
709 | |
710 bool WidgetGtk::IsVisible() const { | |
711 return GTK_WIDGET_VISIBLE(widget_); | |
712 } | |
713 | |
714 bool WidgetGtk::IsActive() const { | |
715 DCHECK(type_ != TYPE_CHILD); | |
716 return is_active_; | |
717 } | |
718 | |
719 bool WidgetGtk::IsAccessibleWidget() const { | |
720 return false; | |
721 } | |
722 | |
723 void WidgetGtk::GenerateMousePressedForView(View* view, | 604 void WidgetGtk::GenerateMousePressedForView(View* view, |
724 const gfx::Point& point) { | 605 const gfx::Point& point) { |
725 NOTIMPLEMENTED(); | 606 NOTIMPLEMENTED(); |
726 } | 607 } |
727 | 608 |
728 bool WidgetGtk::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { | 609 bool WidgetGtk::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { |
729 NOTIMPLEMENTED(); | 610 NOTIMPLEMENTED(); |
730 return false; | 611 return false; |
731 } | 612 } |
732 | 613 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 // enough for our uses. | 731 // enough for our uses. |
851 gtk_window_get_size(GTK_WINDOW(widget_), &w, &h); | 732 gtk_window_get_size(GTK_WINDOW(widget_), &w, &h); |
852 } else { | 733 } else { |
853 GetWidgetPositionOnScreen(widget_, &x, &y); | 734 GetWidgetPositionOnScreen(widget_, &x, &y); |
854 w = widget_->allocation.width; | 735 w = widget_->allocation.width; |
855 h = widget_->allocation.height; | 736 h = widget_->allocation.height; |
856 } | 737 } |
857 return gfx::Rect(x, y, w, h); | 738 return gfx::Rect(x, y, w, h); |
858 } | 739 } |
859 | 740 |
| 741 void WidgetGtk::SetBounds(const gfx::Rect& bounds) { |
| 742 if (type_ == TYPE_CHILD) { |
| 743 GtkWidget* parent = gtk_widget_get_parent(widget_); |
| 744 if (GTK_IS_VIEWS_FIXED(parent)) { |
| 745 WidgetGtk* parent_widget = static_cast<WidgetGtk*>( |
| 746 NativeWidget::GetNativeWidgetForNativeView(parent)); |
| 747 parent_widget->PositionChild(widget_, bounds.x(), bounds.y(), |
| 748 bounds.width(), bounds.height()); |
| 749 } else { |
| 750 DCHECK(GTK_IS_FIXED(parent)) |
| 751 << "Parent of WidgetGtk has to be Fixed or ViewsFixed"; |
| 752 // Just request the size if the parent is not WidgetGtk but plain |
| 753 // GtkFixed. WidgetGtk does not know the minimum size so we assume |
| 754 // the caller of the SetBounds knows exactly how big it wants to be. |
| 755 gtk_widget_set_size_request(widget_, bounds.width(), bounds.height()); |
| 756 if (parent != null_parent_) |
| 757 gtk_fixed_move(GTK_FIXED(parent), widget_, bounds.x(), bounds.y()); |
| 758 } |
| 759 } else { |
| 760 if (GTK_WIDGET_MAPPED(widget_)) { |
| 761 // If the widget is mapped (on screen), we can move and resize with one |
| 762 // call, which avoids two separate window manager steps. |
| 763 gdk_window_move_resize(widget_->window, bounds.x(), bounds.y(), |
| 764 bounds.width(), bounds.height()); |
| 765 } |
| 766 |
| 767 // Always call gtk_window_move and gtk_window_resize so that GtkWindow's |
| 768 // geometry info is up-to-date. |
| 769 GtkWindow* gtk_window = GTK_WINDOW(widget_); |
| 770 // TODO: this may need to set an initial size if not showing. |
| 771 // TODO: need to constrain based on screen size. |
| 772 if (!bounds.IsEmpty()) { |
| 773 gtk_window_resize(gtk_window, bounds.width(), bounds.height()); |
| 774 } |
| 775 gtk_window_move(gtk_window, bounds.x(), bounds.y()); |
| 776 } |
| 777 } |
| 778 |
| 779 void WidgetGtk::MoveAbove(Widget* widget) { |
| 780 DCHECK(widget_); |
| 781 DCHECK(widget_->window); |
| 782 // TODO(oshima): gdk_window_restack is not available in gtk2.0, so |
| 783 // we're simply raising the window to the top. We should switch to |
| 784 // gdk_window_restack when we upgrade gtk to 2.18 or up. |
| 785 gdk_window_raise(widget_->window); |
| 786 } |
| 787 |
| 788 void WidgetGtk::SetShape(gfx::NativeRegion region) { |
| 789 DCHECK(widget_); |
| 790 DCHECK(widget_->window); |
| 791 gdk_window_shape_combine_region(widget_->window, region, 0, 0); |
| 792 gdk_region_destroy(region); |
| 793 } |
| 794 |
| 795 void WidgetGtk::Close() { |
| 796 if (!widget_) |
| 797 return; // No need to do anything. |
| 798 |
| 799 // Hide first. |
| 800 Hide(); |
| 801 if (close_widget_factory_.empty()) { |
| 802 // And we delay the close just in case we're on the stack. |
| 803 MessageLoop::current()->PostTask(FROM_HERE, |
| 804 close_widget_factory_.NewRunnableMethod( |
| 805 &WidgetGtk::CloseNow)); |
| 806 } |
| 807 } |
| 808 |
| 809 void WidgetGtk::CloseNow() { |
| 810 if (widget_) { |
| 811 gtk_widget_destroy(widget_); // Triggers OnDestroy(). |
| 812 } |
| 813 } |
| 814 |
| 815 void WidgetGtk::Show() { |
| 816 if (widget_) { |
| 817 gtk_widget_show(widget_); |
| 818 if (widget_->window) |
| 819 gdk_window_raise(widget_->window); |
| 820 } |
| 821 } |
| 822 |
| 823 void WidgetGtk::Hide() { |
| 824 if (widget_) { |
| 825 gtk_widget_hide(widget_); |
| 826 if (widget_->window) |
| 827 gdk_window_lower(widget_->window); |
| 828 } |
| 829 } |
| 830 |
| 831 void WidgetGtk::SetOpacity(unsigned char opacity) { |
| 832 opacity_ = opacity; |
| 833 if (widget_) { |
| 834 // We can only set the opacity when the widget has been realized. |
| 835 gdk_window_set_opacity(widget_->window, static_cast<gdouble>(opacity) / |
| 836 static_cast<gdouble>(255)); |
| 837 } |
| 838 } |
| 839 |
| 840 void WidgetGtk::SetAlwaysOnTop(bool on_top) { |
| 841 DCHECK(type_ != TYPE_CHILD); |
| 842 always_on_top_ = on_top; |
| 843 if (widget_) |
| 844 gtk_window_set_keep_above(GTK_WINDOW(widget_), on_top); |
| 845 } |
| 846 |
| 847 bool WidgetGtk::IsVisible() const { |
| 848 return GTK_WIDGET_VISIBLE(widget_); |
| 849 } |
| 850 |
| 851 bool WidgetGtk::IsActive() const { |
| 852 DCHECK(type_ != TYPE_CHILD); |
| 853 return is_active_; |
| 854 } |
| 855 |
| 856 bool WidgetGtk::IsAccessibleWidget() const { |
| 857 return false; |
| 858 } |
| 859 |
860 bool WidgetGtk::ContainsNativeView(gfx::NativeView native_view) const { | 860 bool WidgetGtk::ContainsNativeView(gfx::NativeView native_view) const { |
861 // TODO(port) See implementation in WidgetWin::ContainsNativeView. | 861 // TODO(port) See implementation in WidgetWin::ContainsNativeView. |
862 NOTREACHED() << "WidgetGtk::ContainsNativeView is not implemented."; | 862 NOTREACHED() << "WidgetGtk::ContainsNativeView is not implemented."; |
863 return false; | 863 return false; |
864 } | 864 } |
865 | 865 |
866 void WidgetGtk::RunShellDrag(View* view, | 866 void WidgetGtk::RunShellDrag(View* view, |
867 const ui::OSExchangeData& data, | 867 const ui::OSExchangeData& data, |
868 int operation) { | 868 int operation) { |
869 DoDrag(data, operation); | 869 DoDrag(data, operation); |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 | 1578 |
1579 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); | 1579 NativeWidget* native_widget = GetNativeWidgetForNativeView(native_view); |
1580 if (native_widget) | 1580 if (native_widget) |
1581 children->insert(native_widget); | 1581 children->insert(native_widget); |
1582 gtk_container_foreach(GTK_CONTAINER(native_view), | 1582 gtk_container_foreach(GTK_CONTAINER(native_view), |
1583 EnumerateChildWidgetsForNativeWidgets, | 1583 EnumerateChildWidgetsForNativeWidgets, |
1584 reinterpret_cast<gpointer>(children)); | 1584 reinterpret_cast<gpointer>(children)); |
1585 } | 1585 } |
1586 | 1586 |
1587 } // namespace views | 1587 } // namespace views |
OLD | NEW |