| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/gtk/tabs/tab_strip_gtk.h" | 5 #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "app/gtk_dnd_util.h" | 9 #include "app/gtk_dnd_util.h" |
| 10 #include "app/resource_bundle.h" | 10 #include "app/resource_bundle.h" |
| 11 #include "app/slide_animation.h" | 11 #include "app/slide_animation.h" |
| 12 #include "base/i18n/rtl.h" | 12 #include "base/i18n/rtl.h" |
| 13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "chrome/browser/autocomplete/autocomplete.h" | 14 #include "chrome/browser/autocomplete/autocomplete.h" |
| 15 #include "chrome/browser/gtk/browser_window_gtk.h" | 15 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 16 #include "chrome/browser/gtk/custom_button.h" | 16 #include "chrome/browser/gtk/custom_button.h" |
| 17 #include "chrome/browser/gtk/gtk_theme_provider.h" | 17 #include "chrome/browser/gtk/gtk_theme_provider.h" |
| 18 #include "chrome/browser/gtk/gtk_util.h" | 18 #include "chrome/browser/gtk/gtk_util.h" |
| 19 #include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h" | 19 #include "chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h" |
| 20 #include "chrome/browser/profile.h" | 20 #include "chrome/browser/profile.h" |
| 21 #include "chrome/browser/tab_contents/tab_contents.h" | 21 #include "chrome/browser/tab_contents/tab_contents.h" |
| 22 #include "chrome/browser/tab_contents_wrapper.h" |
| 22 #include "chrome/browser/tabs/tab_strip_model_delegate.h" | 23 #include "chrome/browser/tabs/tab_strip_model_delegate.h" |
| 23 #include "chrome/browser/themes/browser_theme_provider.h" | 24 #include "chrome/browser/themes/browser_theme_provider.h" |
| 24 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
| 25 #include "chrome/browser/ui/browser_navigator.h" | 26 #include "chrome/browser/ui/browser_navigator.h" |
| 26 #include "chrome/common/notification_service.h" | 27 #include "chrome/common/notification_service.h" |
| 27 #include "chrome/common/notification_type.h" | 28 #include "chrome/common/notification_type.h" |
| 28 #include "gfx/gtk_util.h" | 29 #include "gfx/gtk_util.h" |
| 29 #include "gfx/point.h" | 30 #include "gfx/point.h" |
| 30 #include "grit/app_resources.h" | 31 #include "grit/app_resources.h" |
| 31 #include "grit/theme_resources.h" | 32 #include "grit/theme_resources.h" |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 bounds_ = bounds; | 806 bounds_ = bounds; |
| 806 } | 807 } |
| 807 | 808 |
| 808 void TabStripGtk::UpdateLoadingAnimations() { | 809 void TabStripGtk::UpdateLoadingAnimations() { |
| 809 for (int i = 0, index = 0; i < GetTabCount(); ++i, ++index) { | 810 for (int i = 0, index = 0; i < GetTabCount(); ++i, ++index) { |
| 810 TabGtk* current_tab = GetTabAt(i); | 811 TabGtk* current_tab = GetTabAt(i); |
| 811 if (current_tab->closing()) { | 812 if (current_tab->closing()) { |
| 812 --index; | 813 --index; |
| 813 } else { | 814 } else { |
| 814 TabRendererGtk::AnimationState state; | 815 TabRendererGtk::AnimationState state; |
| 815 TabContents* contents = model_->GetTabContentsAt(index); | 816 TabContentsWrapper* contents = model_->GetTabContentsAt(index); |
| 816 if (!contents || !contents->is_loading()) { | 817 if (!contents || !contents->tab_contents()->is_loading()) { |
| 817 state = TabGtk::ANIMATION_NONE; | 818 state = TabGtk::ANIMATION_NONE; |
| 818 } else if (contents->waiting_for_response()) { | 819 } else if (contents->tab_contents()->waiting_for_response()) { |
| 819 state = TabGtk::ANIMATION_WAITING; | 820 state = TabGtk::ANIMATION_WAITING; |
| 820 } else { | 821 } else { |
| 821 state = TabGtk::ANIMATION_LOADING; | 822 state = TabGtk::ANIMATION_LOADING; |
| 822 } | 823 } |
| 823 if (current_tab->ValidateLoadingAnimation(state)) { | 824 if (current_tab->ValidateLoadingAnimation(state)) { |
| 824 // Queue the tab's icon area to be repainted. | 825 // Queue the tab's icon area to be repainted. |
| 825 gfx::Rect favicon_bounds = current_tab->favicon_bounds(); | 826 gfx::Rect favicon_bounds = current_tab->favicon_bounds(); |
| 826 gtk_widget_queue_draw_area(tabstrip_.get(), | 827 gtk_widget_queue_draw_area(tabstrip_.get(), |
| 827 favicon_bounds.x() + current_tab->x(), | 828 favicon_bounds.x() + current_tab->x(), |
| 828 favicon_bounds.y() + current_tab->y(), | 829 favicon_bounds.y() + current_tab->y(), |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 } | 918 } |
| 918 } | 919 } |
| 919 } | 920 } |
| 920 | 921 |
| 921 return NULL; | 922 return NULL; |
| 922 } | 923 } |
| 923 | 924 |
| 924 //////////////////////////////////////////////////////////////////////////////// | 925 //////////////////////////////////////////////////////////////////////////////// |
| 925 // TabStripGtk, TabStripModelObserver implementation: | 926 // TabStripGtk, TabStripModelObserver implementation: |
| 926 | 927 |
| 927 void TabStripGtk::TabInsertedAt(TabContents* contents, | 928 void TabStripGtk::TabInsertedAt(TabContentsWrapper* contents, |
| 928 int index, | 929 int index, |
| 929 bool foreground) { | 930 bool foreground) { |
| 930 DCHECK(contents); | 931 DCHECK(contents); |
| 931 DCHECK(index == TabStripModel::kNoTab || model_->ContainsIndex(index)); | 932 DCHECK(index == TabStripModel::kNoTab || model_->ContainsIndex(index)); |
| 932 | 933 |
| 933 StopAnimation(); | 934 StopAnimation(); |
| 934 | 935 |
| 935 bool contains_tab = false; | 936 bool contains_tab = false; |
| 936 TabGtk* tab = NULL; | 937 TabGtk* tab = NULL; |
| 937 // First see if this Tab is one that was dragged out of this TabStrip and is | 938 // First see if this Tab is one that was dragged out of this TabStrip and is |
| 938 // now being dragged back in. In this case, the DraggedTabController actually | 939 // now being dragged back in. In this case, the DraggedTabController actually |
| 939 // has the Tab already constructed and we can just insert it into our list | 940 // has the Tab already constructed and we can just insert it into our list |
| 940 // again. | 941 // again. |
| 941 if (IsDragSessionActive()) { | 942 if (IsDragSessionActive()) { |
| 942 tab = drag_controller_->GetDragSourceTabForContents(contents); | 943 tab = drag_controller_->GetDragSourceTabForContents( |
| 944 contents->tab_contents()); |
| 943 if (tab) { | 945 if (tab) { |
| 944 // If the Tab was detached, it would have been animated closed but not | 946 // If the Tab was detached, it would have been animated closed but not |
| 945 // removed, so we need to reset this property. | 947 // removed, so we need to reset this property. |
| 946 tab->set_closing(false); | 948 tab->set_closing(false); |
| 947 tab->ValidateLoadingAnimation(TabRendererGtk::ANIMATION_NONE); | 949 tab->ValidateLoadingAnimation(TabRendererGtk::ANIMATION_NONE); |
| 948 tab->SetVisible(true); | 950 tab->SetVisible(true); |
| 949 } | 951 } |
| 950 | 952 |
| 951 // See if we're already in the list. We don't want to add ourselves twice. | 953 // See if we're already in the list. We don't want to add ourselves twice. |
| 952 std::vector<TabData>::const_iterator iter = tab_data_.begin(); | 954 std::vector<TabData>::const_iterator iter = tab_data_.begin(); |
| 953 for (; iter != tab_data_.end() && !contains_tab; ++iter) { | 955 for (; iter != tab_data_.end() && !contains_tab; ++iter) { |
| 954 if (iter->tab == tab) | 956 if (iter->tab == tab) |
| 955 contains_tab = true; | 957 contains_tab = true; |
| 956 } | 958 } |
| 957 } | 959 } |
| 958 | 960 |
| 959 if (!tab) | 961 if (!tab) |
| 960 tab = new TabGtk(this); | 962 tab = new TabGtk(this); |
| 961 | 963 |
| 962 // Only insert if we're not already in the list. | 964 // Only insert if we're not already in the list. |
| 963 if (!contains_tab) { | 965 if (!contains_tab) { |
| 964 TabData d = { tab, gfx::Rect() }; | 966 TabData d = { tab, gfx::Rect() }; |
| 965 tab_data_.insert(tab_data_.begin() + index, d); | 967 tab_data_.insert(tab_data_.begin() + index, d); |
| 966 tab->UpdateData(contents, model_->IsAppTab(index), false); | 968 tab->UpdateData(contents->tab_contents(), model_->IsAppTab(index), false); |
| 967 } | 969 } |
| 968 tab->set_mini(model_->IsMiniTab(index)); | 970 tab->set_mini(model_->IsMiniTab(index)); |
| 969 tab->set_app(model_->IsAppTab(index)); | 971 tab->set_app(model_->IsAppTab(index)); |
| 970 tab->SetBlocked(model_->IsTabBlocked(index)); | 972 tab->SetBlocked(model_->IsTabBlocked(index)); |
| 971 | 973 |
| 972 if (gtk_widget_get_parent(tab->widget()) != tabstrip_.get()) | 974 if (gtk_widget_get_parent(tab->widget()) != tabstrip_.get()) |
| 973 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), tab->widget(), 0, 0); | 975 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), tab->widget(), 0, 0); |
| 974 | 976 |
| 975 // Don't animate the first tab; it looks weird. | 977 // Don't animate the first tab; it looks weird. |
| 976 if (GetTabCount() > 1) { | 978 if (GetTabCount() > 1) { |
| 977 StartInsertTabAnimation(index); | 979 StartInsertTabAnimation(index); |
| 978 // We added the tab at 0x0, we need to force an animation step otherwise | 980 // We added the tab at 0x0, we need to force an animation step otherwise |
| 979 // if GTK paints before the animation event the tab is painted at 0x0 | 981 // if GTK paints before the animation event the tab is painted at 0x0 |
| 980 // which is most likely not where it should be positioned. | 982 // which is most likely not where it should be positioned. |
| 981 active_animation_->AnimationProgressed(NULL); | 983 active_animation_->AnimationProgressed(NULL); |
| 982 } else { | 984 } else { |
| 983 Layout(); | 985 Layout(); |
| 984 } | 986 } |
| 985 } | 987 } |
| 986 | 988 |
| 987 void TabStripGtk::TabDetachedAt(TabContents* contents, int index) { | 989 void TabStripGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { |
| 988 GenerateIdealBounds(); | 990 GenerateIdealBounds(); |
| 989 StartRemoveTabAnimation(index, contents); | 991 StartRemoveTabAnimation(index, contents->tab_contents()); |
| 990 // Have to do this _after_ calling StartRemoveTabAnimation, so that any | 992 // Have to do this _after_ calling StartRemoveTabAnimation, so that any |
| 991 // previous remove is completed fully and index is valid in sync with the | 993 // previous remove is completed fully and index is valid in sync with the |
| 992 // model index. | 994 // model index. |
| 993 GetTabAt(index)->set_closing(true); | 995 GetTabAt(index)->set_closing(true); |
| 994 } | 996 } |
| 995 | 997 |
| 996 void TabStripGtk::TabSelectedAt(TabContents* old_contents, | 998 void TabStripGtk::TabSelectedAt(TabContentsWrapper* old_contents, |
| 997 TabContents* new_contents, | 999 TabContentsWrapper* new_contents, |
| 998 int index, | 1000 int index, |
| 999 bool user_gesture) { | 1001 bool user_gesture) { |
| 1000 DCHECK(index >= 0 && index < static_cast<int>(GetTabCount())); | 1002 DCHECK(index >= 0 && index < static_cast<int>(GetTabCount())); |
| 1001 | 1003 |
| 1002 // We have "tiny tabs" if the tabs are so tiny that the unselected ones are | 1004 // We have "tiny tabs" if the tabs are so tiny that the unselected ones are |
| 1003 // a different size to the selected ones. | 1005 // a different size to the selected ones. |
| 1004 bool tiny_tabs = current_unselected_width_ != current_selected_width_; | 1006 bool tiny_tabs = current_unselected_width_ != current_selected_width_; |
| 1005 if (!IsAnimating() && (!needs_resize_layout_ || tiny_tabs)) | 1007 if (!IsAnimating() && (!needs_resize_layout_ || tiny_tabs)) |
| 1006 Layout(); | 1008 Layout(); |
| 1007 | 1009 |
| 1008 GetTabAt(index)->SchedulePaint(); | 1010 GetTabAt(index)->SchedulePaint(); |
| 1009 | 1011 |
| 1010 int old_index = model_->GetIndexOfTabContents(old_contents); | 1012 int old_index = model_->GetIndexOfTabContents(old_contents); |
| 1011 if (old_index >= 0) { | 1013 if (old_index >= 0) { |
| 1012 GetTabAt(old_index)->SchedulePaint(); | 1014 GetTabAt(old_index)->SchedulePaint(); |
| 1013 GetTabAt(old_index)->StopMiniTabTitleAnimation(); | 1015 GetTabAt(old_index)->StopMiniTabTitleAnimation(); |
| 1014 } | 1016 } |
| 1015 } | 1017 } |
| 1016 | 1018 |
| 1017 void TabStripGtk::TabMoved(TabContents* contents, | 1019 void TabStripGtk::TabMoved(TabContentsWrapper* contents, |
| 1018 int from_index, | 1020 int from_index, |
| 1019 int to_index) { | 1021 int to_index) { |
| 1020 gfx::Rect start_bounds = GetIdealBounds(from_index); | 1022 gfx::Rect start_bounds = GetIdealBounds(from_index); |
| 1021 TabGtk* tab = GetTabAt(from_index); | 1023 TabGtk* tab = GetTabAt(from_index); |
| 1022 tab_data_.erase(tab_data_.begin() + from_index); | 1024 tab_data_.erase(tab_data_.begin() + from_index); |
| 1023 TabData data = {tab, gfx::Rect()}; | 1025 TabData data = {tab, gfx::Rect()}; |
| 1024 tab->set_mini(model_->IsMiniTab(to_index)); | 1026 tab->set_mini(model_->IsMiniTab(to_index)); |
| 1025 tab->SetBlocked(model_->IsTabBlocked(to_index)); | 1027 tab->SetBlocked(model_->IsTabBlocked(to_index)); |
| 1026 tab_data_.insert(tab_data_.begin() + to_index, data); | 1028 tab_data_.insert(tab_data_.begin() + to_index, data); |
| 1027 GenerateIdealBounds(); | 1029 GenerateIdealBounds(); |
| 1028 StartMoveTabAnimation(from_index, to_index); | 1030 StartMoveTabAnimation(from_index, to_index); |
| 1029 } | 1031 } |
| 1030 | 1032 |
| 1031 void TabStripGtk::TabChangedAt(TabContents* contents, int index, | 1033 void TabStripGtk::TabChangedAt(TabContentsWrapper* contents, int index, |
| 1032 TabChangeType change_type) { | 1034 TabChangeType change_type) { |
| 1033 // Index is in terms of the model. Need to make sure we adjust that index in | 1035 // Index is in terms of the model. Need to make sure we adjust that index in |
| 1034 // case we have an animation going. | 1036 // case we have an animation going. |
| 1035 TabGtk* tab = GetTabAtAdjustForAnimation(index); | 1037 TabGtk* tab = GetTabAtAdjustForAnimation(index); |
| 1036 if (change_type == TITLE_NOT_LOADING) { | 1038 if (change_type == TITLE_NOT_LOADING) { |
| 1037 if (tab->mini() && !tab->IsSelected()) | 1039 if (tab->mini() && !tab->IsSelected()) |
| 1038 tab->StartMiniTabTitleAnimation(); | 1040 tab->StartMiniTabTitleAnimation(); |
| 1039 // We'll receive another notification of the change asynchronously. | 1041 // We'll receive another notification of the change asynchronously. |
| 1040 return; | 1042 return; |
| 1041 } | 1043 } |
| 1042 tab->UpdateData(contents, | 1044 tab->UpdateData(contents->tab_contents(), |
| 1043 model_->IsAppTab(index), | 1045 model_->IsAppTab(index), |
| 1044 change_type == LOADING_ONLY); | 1046 change_type == LOADING_ONLY); |
| 1045 tab->UpdateFromModel(); | 1047 tab->UpdateFromModel(); |
| 1046 } | 1048 } |
| 1047 | 1049 |
| 1048 void TabStripGtk::TabReplacedAt(TabContents* old_contents, | 1050 void TabStripGtk::TabReplacedAt(TabContentsWrapper* old_contents, |
| 1049 TabContents* new_contents, | 1051 TabContentsWrapper* new_contents, |
| 1050 int index) { | 1052 int index) { |
| 1051 TabChangedAt(new_contents, index, ALL); | 1053 TabChangedAt(new_contents, index, ALL); |
| 1052 } | 1054 } |
| 1053 | 1055 |
| 1054 void TabStripGtk::TabMiniStateChanged(TabContents* contents, int index) { | 1056 void TabStripGtk::TabMiniStateChanged(TabContentsWrapper* contents, int index) { |
| 1055 // Don't do anything if we've already picked up the change from TabMoved. | 1057 // Don't do anything if we've already picked up the change from TabMoved. |
| 1056 if (GetTabAt(index)->mini() == model_->IsMiniTab(index)) | 1058 if (GetTabAt(index)->mini() == model_->IsMiniTab(index)) |
| 1057 return; | 1059 return; |
| 1058 | 1060 |
| 1059 GetTabAt(index)->set_mini(model_->IsMiniTab(index)); | 1061 GetTabAt(index)->set_mini(model_->IsMiniTab(index)); |
| 1060 // Don't animate if the window isn't visible yet. The window won't be visible | 1062 // Don't animate if the window isn't visible yet. The window won't be visible |
| 1061 // when dragging a mini-tab to a new window. | 1063 // when dragging a mini-tab to a new window. |
| 1062 if (window_ && window_->window() && | 1064 if (window_ && window_->window() && |
| 1063 GTK_WIDGET_VISIBLE(GTK_WIDGET(window_->window()))) { | 1065 GTK_WIDGET_VISIBLE(GTK_WIDGET(window_->window()))) { |
| 1064 StartMiniTabAnimation(index); | 1066 StartMiniTabAnimation(index); |
| 1065 } else { | 1067 } else { |
| 1066 Layout(); | 1068 Layout(); |
| 1067 } | 1069 } |
| 1068 } | 1070 } |
| 1069 | 1071 |
| 1070 void TabStripGtk::TabBlockedStateChanged(TabContents* contents, int index) { | 1072 void TabStripGtk::TabBlockedStateChanged(TabContentsWrapper* contents, |
| 1073 int index) { |
| 1071 GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index)); | 1074 GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index)); |
| 1072 } | 1075 } |
| 1073 | 1076 |
| 1074 //////////////////////////////////////////////////////////////////////////////// | 1077 //////////////////////////////////////////////////////////////////////////////// |
| 1075 // TabStripGtk, TabGtk::TabDelegate implementation: | 1078 // TabStripGtk, TabGtk::TabDelegate implementation: |
| 1076 | 1079 |
| 1077 bool TabStripGtk::IsTabSelected(const TabGtk* tab) const { | 1080 bool TabStripGtk::IsTabSelected(const TabGtk* tab) const { |
| 1078 if (tab->closing()) | 1081 if (tab->closing()) |
| 1079 return false; | 1082 return false; |
| 1080 | 1083 |
| (...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1968 case 1: | 1971 case 1: |
| 1969 model_->delegate()->AddBlankTab(true); | 1972 model_->delegate()->AddBlankTab(true); |
| 1970 break; | 1973 break; |
| 1971 case 2: { | 1974 case 2: { |
| 1972 // On middle-click, try to parse the PRIMARY selection as a URL and load | 1975 // On middle-click, try to parse the PRIMARY selection as a URL and load |
| 1973 // it instead of creating a blank page. | 1976 // it instead of creating a blank page. |
| 1974 GURL url; | 1977 GURL url; |
| 1975 if (!gtk_util::URLFromPrimarySelection(model_->profile(), &url)) | 1978 if (!gtk_util::URLFromPrimarySelection(model_->profile(), &url)) |
| 1976 return; | 1979 return; |
| 1977 | 1980 |
| 1981 <<<<<<< .mine |
| 1982 TabContentsWrapper* contents = |
| 1983 model_->delegate()->CreateTabContentsForURL( |
| 1984 url, |
| 1985 GURL(), // referrer |
| 1986 model_->profile(), |
| 1987 PageTransition::TYPED, |
| 1988 false, // defer_load |
| 1989 NULL); // instance |
| 1990 model_->AddTabContents( |
| 1991 contents, |
| 1992 -1, // index |
| 1993 PageTransition::TYPED, |
| 1994 TabStripModel::ADD_SELECTED); |
| 1995 ======= |
| 1978 Browser* browser = window_->browser(); | 1996 Browser* browser = window_->browser(); |
| 1979 DCHECK(browser); | 1997 DCHECK(browser); |
| 1980 browser->AddSelectedTabWithURL(url, PageTransition::TYPED); | 1998 browser->AddSelectedTabWithURL(url, PageTransition::TYPED); |
| 1999 >>>>>>> .r66288 |
| 1981 break; | 2000 break; |
| 1982 } | 2001 } |
| 1983 default: | 2002 default: |
| 1984 NOTREACHED() << "Got click on new tab button with unhandled mouse " | 2003 NOTREACHED() << "Got click on new tab button with unhandled mouse " |
| 1985 << "button " << mouse_button; | 2004 << "button " << mouse_button; |
| 1986 } | 2005 } |
| 1987 } | 2006 } |
| 1988 | 2007 |
| 1989 void TabStripGtk::SetTabBounds(TabGtk* tab, const gfx::Rect& bounds) { | 2008 void TabStripGtk::SetTabBounds(TabGtk* tab, const gfx::Rect& bounds) { |
| 1990 gfx::Rect bds = bounds; | 2009 gfx::Rect bds = bounds; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 | 2045 |
| 2027 // Let the middle mouse button initiate clicks as well. | 2046 // Let the middle mouse button initiate clicks as well. |
| 2028 gtk_util::SetButtonTriggersNavigation(button->widget()); | 2047 gtk_util::SetButtonTriggersNavigation(button->widget()); |
| 2029 g_signal_connect(button->widget(), "clicked", | 2048 g_signal_connect(button->widget(), "clicked", |
| 2030 G_CALLBACK(OnNewTabClickedThunk), this); | 2049 G_CALLBACK(OnNewTabClickedThunk), this); |
| 2031 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); | 2050 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); |
| 2032 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); | 2051 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); |
| 2033 | 2052 |
| 2034 return button; | 2053 return button; |
| 2035 } | 2054 } |
| OLD | NEW |