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" |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 gtk_drag_dest_set(tabstrip_.get(), GTK_DEST_DEFAULT_ALL, | 730 gtk_drag_dest_set(tabstrip_.get(), GTK_DEST_DEFAULT_ALL, |
731 NULL, 0, | 731 NULL, 0, |
732 static_cast<GdkDragAction>( | 732 static_cast<GdkDragAction>( |
733 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); | 733 GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); |
734 static const int targets[] = { gtk_dnd_util::TEXT_URI_LIST, | 734 static const int targets[] = { gtk_dnd_util::TEXT_URI_LIST, |
735 gtk_dnd_util::NETSCAPE_URL, | 735 gtk_dnd_util::NETSCAPE_URL, |
736 -1 }; | 736 -1 }; |
737 gtk_dnd_util::SetDestTargetList(tabstrip_.get(), targets); | 737 gtk_dnd_util::SetDestTargetList(tabstrip_.get(), targets); |
738 | 738 |
739 g_signal_connect(tabstrip_.get(), "expose-event", | 739 g_signal_connect(tabstrip_.get(), "expose-event", |
740 G_CALLBACK(OnExpose), this); | 740 G_CALLBACK(OnExposeThunk), this); |
741 g_signal_connect(tabstrip_.get(), "size-allocate", | 741 g_signal_connect(tabstrip_.get(), "size-allocate", |
742 G_CALLBACK(OnSizeAllocate), this); | 742 G_CALLBACK(OnSizeAllocateThunk), this); |
743 g_signal_connect(tabstrip_.get(), "drag-motion", | 743 g_signal_connect(tabstrip_.get(), "drag-motion", |
744 G_CALLBACK(OnDragMotion), this); | 744 G_CALLBACK(OnDragMotionThunk), this); |
745 g_signal_connect(tabstrip_.get(), "drag-drop", | 745 g_signal_connect(tabstrip_.get(), "drag-drop", |
746 G_CALLBACK(OnDragDrop), this); | 746 G_CALLBACK(OnDragDropThunk), this); |
747 g_signal_connect(tabstrip_.get(), "drag-leave", | 747 g_signal_connect(tabstrip_.get(), "drag-leave", |
748 G_CALLBACK(OnDragLeave), this); | 748 G_CALLBACK(OnDragLeaveThunk), this); |
749 g_signal_connect(tabstrip_.get(), "drag-data-received", | 749 g_signal_connect(tabstrip_.get(), "drag-data-received", |
750 G_CALLBACK(OnDragDataReceived), this); | 750 G_CALLBACK(OnDragDataReceivedThunk), this); |
751 | 751 |
752 newtab_button_.reset(MakeNewTabButton()); | 752 newtab_button_.reset(MakeNewTabButton()); |
753 | 753 |
754 gtk_widget_show_all(tabstrip_.get()); | 754 gtk_widget_show_all(tabstrip_.get()); |
755 | 755 |
756 bounds_ = GetInitialWidgetBounds(tabstrip_.get()); | 756 bounds_ = GetInitialWidgetBounds(tabstrip_.get()); |
757 | 757 |
758 if (drop_indicator_width == 0) { | 758 if (drop_indicator_width == 0) { |
759 // Direction doesn't matter, both images are the same size. | 759 // Direction doesn't matter, both images are the same size. |
760 GdkPixbuf* drop_image = GetDropArrowImage(true); | 760 GdkPixbuf* drop_image = GetDropArrowImage(true); |
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1637 drop_before(drop_before), | 1637 drop_before(drop_before), |
1638 point_down(point_down) { | 1638 point_down(point_down) { |
1639 CreateContainer(); | 1639 CreateContainer(); |
1640 drop_arrow = GetDropArrowImage(point_down); | 1640 drop_arrow = GetDropArrowImage(point_down); |
1641 } | 1641 } |
1642 | 1642 |
1643 TabStripGtk::DropInfo::~DropInfo() { | 1643 TabStripGtk::DropInfo::~DropInfo() { |
1644 DestroyContainer(); | 1644 DestroyContainer(); |
1645 } | 1645 } |
1646 | 1646 |
1647 // static | |
1648 gboolean TabStripGtk::DropInfo::OnExposeEvent(GtkWidget* widget, | 1647 gboolean TabStripGtk::DropInfo::OnExposeEvent(GtkWidget* widget, |
1649 GdkEventExpose* event, | 1648 GdkEventExpose* event) { |
1650 DropInfo* drop_info) { | |
1651 if (gtk_util::IsScreenComposited()) { | 1649 if (gtk_util::IsScreenComposited()) { |
1652 drop_info->SetContainerTransparency(); | 1650 SetContainerTransparency(); |
1653 } else { | 1651 } else { |
1654 drop_info->SetContainerShapeMask(); | 1652 SetContainerShapeMask(); |
1655 } | 1653 } |
1656 | 1654 |
1657 gdk_pixbuf_render_to_drawable(drop_info->drop_arrow, | 1655 gdk_pixbuf_render_to_drawable(drop_arrow, |
1658 drop_info->container->window, | 1656 container->window, |
1659 0, 0, 0, | 1657 0, 0, 0, |
1660 0, 0, | 1658 0, 0, |
1661 drop_indicator_width, | 1659 drop_indicator_width, |
1662 drop_indicator_height, | 1660 drop_indicator_height, |
1663 GDK_RGB_DITHER_NONE, 0, 0); | 1661 GDK_RGB_DITHER_NONE, 0, 0); |
1664 | 1662 |
1665 return FALSE; | 1663 return FALSE; |
1666 } | 1664 } |
1667 | 1665 |
1668 // Sets the color map of the container window to allow the window to be | 1666 // Sets the color map of the container window to allow the window to be |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 // Set the shape mask. | 1717 // Set the shape mask. |
1720 gdk_window_shape_combine_mask(container->window, pixmap, 0, 0); | 1718 gdk_window_shape_combine_mask(container->window, pixmap, 0, 0); |
1721 g_object_unref(pixmap); | 1719 g_object_unref(pixmap); |
1722 } | 1720 } |
1723 | 1721 |
1724 void TabStripGtk::DropInfo::CreateContainer() { | 1722 void TabStripGtk::DropInfo::CreateContainer() { |
1725 container = gtk_window_new(GTK_WINDOW_POPUP); | 1723 container = gtk_window_new(GTK_WINDOW_POPUP); |
1726 SetContainerColorMap(); | 1724 SetContainerColorMap(); |
1727 gtk_widget_set_app_paintable(container, TRUE); | 1725 gtk_widget_set_app_paintable(container, TRUE); |
1728 g_signal_connect(container, "expose-event", | 1726 g_signal_connect(container, "expose-event", |
1729 G_CALLBACK(OnExposeEvent), this); | 1727 G_CALLBACK(OnExposeEventThunk), this); |
1730 gtk_widget_add_events(container, GDK_STRUCTURE_MASK); | 1728 gtk_widget_add_events(container, GDK_STRUCTURE_MASK); |
1731 gtk_window_move(GTK_WINDOW(container), 0, 0); | 1729 gtk_window_move(GTK_WINDOW(container), 0, 0); |
1732 gtk_window_resize(GTK_WINDOW(container), | 1730 gtk_window_resize(GTK_WINDOW(container), |
1733 drop_indicator_width, drop_indicator_height); | 1731 drop_indicator_width, drop_indicator_height); |
1734 gtk_widget_show_all(container); | 1732 gtk_widget_show_all(container); |
1735 } | 1733 } |
1736 | 1734 |
1737 void TabStripGtk::DropInfo::DestroyContainer() { | 1735 void TabStripGtk::DropInfo::DestroyContainer() { |
1738 if (GTK_IS_WIDGET(container)) | 1736 if (GTK_IS_WIDGET(container)) |
1739 gtk_widget_destroy(container); | 1737 gtk_widget_destroy(container); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 active_animation_.reset(NULL); | 1818 active_animation_.reset(NULL); |
1821 | 1819 |
1822 // Reset the animation state of each tab. | 1820 // Reset the animation state of each tab. |
1823 for (int i = 0, count = GetTabCount(); i < count; ++i) | 1821 for (int i = 0, count = GetTabCount(); i < count; ++i) |
1824 GetTabAt(i)->set_animating_mini_change(false); | 1822 GetTabAt(i)->set_animating_mini_change(false); |
1825 | 1823 |
1826 if (layout) | 1824 if (layout) |
1827 Layout(); | 1825 Layout(); |
1828 } | 1826 } |
1829 | 1827 |
1830 // static | 1828 gboolean TabStripGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event) { |
1831 gboolean TabStripGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event, | |
1832 TabStripGtk* tabstrip) { | |
1833 if (gdk_region_empty(event->region)) | 1829 if (gdk_region_empty(event->region)) |
1834 return TRUE; | 1830 return TRUE; |
1835 | 1831 |
1836 // If we're only repainting favicons, optimize the paint path and only draw | 1832 // If we're only repainting favicons, optimize the paint path and only draw |
1837 // the favicons. | 1833 // the favicons. |
1838 GdkRectangle* rects; | 1834 GdkRectangle* rects; |
1839 gint num_rects; | 1835 gint num_rects; |
1840 gdk_region_get_rectangles(event->region, &rects, &num_rects); | 1836 gdk_region_get_rectangles(event->region, &rects, &num_rects); |
1841 qsort(rects, num_rects, sizeof(GdkRectangle), CompareGdkRectangles); | 1837 qsort(rects, num_rects, sizeof(GdkRectangle), CompareGdkRectangles); |
1842 std::vector<int> tabs_to_repaint; | 1838 std::vector<int> tabs_to_repaint; |
1843 if (!tabstrip->IsDragSessionActive() && | 1839 if (!IsDragSessionActive() && |
1844 tabstrip->CanPaintOnlyFavIcons(rects, num_rects, &tabs_to_repaint)) { | 1840 CanPaintOnlyFavIcons(rects, num_rects, &tabs_to_repaint)) { |
1845 tabstrip->PaintOnlyFavIcons(event, tabs_to_repaint); | 1841 PaintOnlyFavIcons(event, tabs_to_repaint); |
1846 g_free(rects); | 1842 g_free(rects); |
1847 return TRUE; | 1843 return TRUE; |
1848 } | 1844 } |
1849 g_free(rects); | 1845 g_free(rects); |
1850 | 1846 |
1851 // TODO(jhawkins): Ideally we'd like to only draw what's needed in the damage | 1847 // TODO(jhawkins): Ideally we'd like to only draw what's needed in the damage |
1852 // rect, but the tab widgets overlap each other, and painting on one widget | 1848 // rect, but the tab widgets overlap each other, and painting on one widget |
1853 // will cause an expose-event to be sent to the widgets underneath. The | 1849 // will cause an expose-event to be sent to the widgets underneath. The |
1854 // underlying widget does not need to be redrawn as we control the order of | 1850 // underlying widget does not need to be redrawn as we control the order of |
1855 // expose-events. Currently we hack it to redraw the entire tabstrip. We | 1851 // expose-events. Currently we hack it to redraw the entire tabstrip. We |
1856 // could change the damage rect to just contain the tabs + the new tab button. | 1852 // could change the damage rect to just contain the tabs + the new tab button. |
1857 event->area.x = 0; | 1853 event->area.x = 0; |
1858 event->area.y = 0; | 1854 event->area.y = 0; |
1859 event->area.width = tabstrip->bounds_.width(); | 1855 event->area.width = bounds_.width(); |
1860 event->area.height = tabstrip->bounds_.height(); | 1856 event->area.height = bounds_.height(); |
1861 gdk_region_union_with_rect(event->region, &event->area); | 1857 gdk_region_union_with_rect(event->region, &event->area); |
1862 | 1858 |
1863 // Paint the New Tab button. | 1859 // Paint the New Tab button. |
1864 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()), | 1860 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), |
1865 tabstrip->newtab_button_->widget(), event); | 1861 newtab_button_->widget(), event); |
1866 | 1862 |
1867 // Paint the tabs in reverse order, so they stack to the left. | 1863 // Paint the tabs in reverse order, so they stack to the left. |
1868 TabGtk* selected_tab = NULL; | 1864 TabGtk* selected_tab = NULL; |
1869 int tab_count = tabstrip->GetTabCount(); | 1865 int tab_count = GetTabCount(); |
1870 for (int i = tab_count - 1; i >= 0; --i) { | 1866 for (int i = tab_count - 1; i >= 0; --i) { |
1871 TabGtk* tab = tabstrip->GetTabAt(i); | 1867 TabGtk* tab = GetTabAt(i); |
1872 // We must ask the _Tab's_ model, not ourselves, because in some situations | 1868 // We must ask the _Tab's_ model, not ourselves, because in some situations |
1873 // the model will be different to this object, e.g. when a Tab is being | 1869 // the model will be different to this object, e.g. when a Tab is being |
1874 // removed after its TabContents has been destroyed. | 1870 // removed after its TabContents has been destroyed. |
1875 if (!tab->IsSelected()) { | 1871 if (!tab->IsSelected()) { |
1876 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()), | 1872 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), |
1877 tab->widget(), event); | 1873 tab->widget(), event); |
1878 } else { | 1874 } else { |
1879 selected_tab = tab; | 1875 selected_tab = tab; |
1880 } | 1876 } |
1881 } | 1877 } |
1882 | 1878 |
1883 // Paint the selected tab last, so it overlaps all the others. | 1879 // Paint the selected tab last, so it overlaps all the others. |
1884 if (selected_tab) { | 1880 if (selected_tab) { |
1885 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()), | 1881 gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()), |
1886 selected_tab->widget(), event); | 1882 selected_tab->widget(), event); |
1887 } | 1883 } |
1888 | 1884 |
1889 return TRUE; | 1885 return TRUE; |
1890 } | 1886 } |
1891 | 1887 |
1892 // static | 1888 void TabStripGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { |
1893 void TabStripGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation, | |
1894 TabStripGtk* tabstrip) { | |
1895 gfx::Rect bounds = gfx::Rect(allocation->x, allocation->y, | 1889 gfx::Rect bounds = gfx::Rect(allocation->x, allocation->y, |
1896 allocation->width, allocation->height); | 1890 allocation->width, allocation->height); |
1897 | 1891 |
1898 // Nothing to do if the bounds are the same. If we don't catch this, we'll | 1892 // Nothing to do if the bounds are the same. If we don't catch this, we'll |
1899 // get an infinite loop of size-allocate signals. | 1893 // get an infinite loop of size-allocate signals. |
1900 if (tabstrip->bounds_ == bounds) | 1894 if (bounds_ == bounds) |
1901 return; | 1895 return; |
1902 | 1896 |
1903 tabstrip->SetBounds(bounds); | 1897 SetBounds(bounds); |
1904 | 1898 |
1905 // No tabs, nothing to layout. This happens when a browser window is created | 1899 // No tabs, nothing to layout. This happens when a browser window is created |
1906 // and shown before tabs are added (as in a popup window). | 1900 // and shown before tabs are added (as in a popup window). |
1907 if (tabstrip->GetTabCount() == 0) | 1901 if (GetTabCount() == 0) |
1908 return; | 1902 return; |
1909 | 1903 |
1910 // Do a regular layout on the first configure-event so we don't animate | 1904 // Do a regular layout on the first configure-event so we don't animate |
1911 // the first tab. | 1905 // the first tab. |
1912 // TODO(jhawkins): Windows resizes the layout tabs continuously during | 1906 // TODO(jhawkins): Windows resizes the layout tabs continuously during |
1913 // a resize. I need to investigate which signal to watch in order to | 1907 // a resize. I need to investigate which signal to watch in order to |
1914 // reproduce this behavior. | 1908 // reproduce this behavior. |
1915 if (tabstrip->GetTabCount() == 1) | 1909 if (GetTabCount() == 1) |
1916 tabstrip->Layout(); | 1910 Layout(); |
1917 else | 1911 else |
1918 tabstrip->ResizeLayoutTabs(); | 1912 ResizeLayoutTabs(); |
1919 } | 1913 } |
1920 | 1914 |
1921 // static | |
1922 gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context, | 1915 gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context, |
1923 gint x, gint y, guint time, | 1916 gint x, gint y, guint time) { |
1924 TabStripGtk* tabstrip) { | 1917 UpdateDropIndex(context, x, y); |
1925 tabstrip->UpdateDropIndex(context, x, y); | |
1926 return TRUE; | 1918 return TRUE; |
1927 } | 1919 } |
1928 | 1920 |
1929 // static | |
1930 gboolean TabStripGtk::OnDragDrop(GtkWidget* widget, GdkDragContext* context, | 1921 gboolean TabStripGtk::OnDragDrop(GtkWidget* widget, GdkDragContext* context, |
1931 gint x, gint y, guint time, | 1922 gint x, gint y, guint time) { |
1932 TabStripGtk* tabstrip) { | 1923 if (!drop_info_.get()) |
1933 if (!tabstrip->drop_info_.get()) | |
1934 return FALSE; | 1924 return FALSE; |
1935 | 1925 |
1936 GdkAtom target = gtk_drag_dest_find_target(widget, context, NULL); | 1926 GdkAtom target = gtk_drag_dest_find_target(widget, context, NULL); |
1937 if (target != GDK_NONE) | 1927 if (target != GDK_NONE) |
1938 gtk_drag_finish(context, FALSE, FALSE, time); | 1928 gtk_drag_finish(context, FALSE, FALSE, time); |
1939 else | 1929 else |
1940 gtk_drag_get_data(widget, context, target, time); | 1930 gtk_drag_get_data(widget, context, target, time); |
1941 | 1931 |
1942 return TRUE; | 1932 return TRUE; |
1943 } | 1933 } |
1944 | 1934 |
1945 // static | |
1946 gboolean TabStripGtk::OnDragLeave(GtkWidget* widget, GdkDragContext* context, | 1935 gboolean TabStripGtk::OnDragLeave(GtkWidget* widget, GdkDragContext* context, |
1947 guint time, TabStripGtk* tabstrip) { | 1936 guint time) { |
1948 // Destroy the drop indicator. | 1937 // Destroy the drop indicator. |
1949 tabstrip->drop_info_->DestroyContainer(); | 1938 drop_info_->DestroyContainer(); |
1950 return FALSE; | 1939 return FALSE; |
1951 } | 1940 } |
1952 | 1941 |
1953 // static | |
1954 gboolean TabStripGtk::OnDragDataReceived(GtkWidget* widget, | 1942 gboolean TabStripGtk::OnDragDataReceived(GtkWidget* widget, |
1955 GdkDragContext* context, | 1943 GdkDragContext* context, |
1956 gint x, gint y, | 1944 gint x, gint y, |
1957 GtkSelectionData* data, | 1945 GtkSelectionData* data, |
1958 guint info, guint time, | 1946 guint info, guint time) { |
1959 TabStripGtk* tabstrip) { | |
1960 bool success = false; | 1947 bool success = false; |
1961 | 1948 |
1962 if (info == gtk_dnd_util::TEXT_URI_LIST || | 1949 if (info == gtk_dnd_util::TEXT_URI_LIST || |
1963 info == gtk_dnd_util::NETSCAPE_URL) { | 1950 info == gtk_dnd_util::NETSCAPE_URL) { |
1964 success = tabstrip->CompleteDrop(data->data); | 1951 success = CompleteDrop(data->data); |
1965 } | 1952 } |
1966 | 1953 |
1967 gtk_drag_finish(context, success, success, time); | 1954 gtk_drag_finish(context, success, success, time); |
1968 return TRUE; | 1955 return TRUE; |
1969 } | 1956 } |
1970 | 1957 |
1971 // static | 1958 void TabStripGtk::OnNewTabClicked(GtkWidget* widget) { |
1972 void TabStripGtk::OnNewTabClicked(GtkWidget* widget, TabStripGtk* tabstrip) { | |
1973 GdkEvent* event = gtk_get_current_event(); | 1959 GdkEvent* event = gtk_get_current_event(); |
1974 DCHECK_EQ(event->type, GDK_BUTTON_RELEASE); | 1960 DCHECK_EQ(event->type, GDK_BUTTON_RELEASE); |
1975 int mouse_button = event->button.button; | 1961 int mouse_button = event->button.button; |
1976 gdk_event_free(event); | 1962 gdk_event_free(event); |
1977 | 1963 |
1978 switch (mouse_button) { | 1964 switch (mouse_button) { |
1979 case 1: | 1965 case 1: |
1980 tabstrip->model_->delegate()->AddBlankTab(true); | 1966 model_->delegate()->AddBlankTab(true); |
1981 break; | 1967 break; |
1982 case 2: { | 1968 case 2: { |
1983 // On middle-click, try to parse the PRIMARY selection as a URL and load | 1969 // On middle-click, try to parse the PRIMARY selection as a URL and load |
1984 // it instead of creating a blank page. | 1970 // it instead of creating a blank page. |
1985 GURL url; | 1971 GURL url; |
1986 if (!gtk_util::URLFromPrimarySelection(tabstrip->model_->profile(), &url)) | 1972 if (!gtk_util::URLFromPrimarySelection(model_->profile(), &url)) |
1987 return; | 1973 return; |
1988 | 1974 |
1989 TabContents* contents = | 1975 TabContents* contents = |
1990 tabstrip->model_->delegate()->CreateTabContentsForURL( | 1976 model_->delegate()->CreateTabContentsForURL( |
1991 url, | 1977 url, |
1992 GURL(), // referrer | 1978 GURL(), // referrer |
1993 tabstrip->model_->profile(), | 1979 model_->profile(), |
1994 PageTransition::TYPED, | 1980 PageTransition::TYPED, |
1995 false, // defer_load | 1981 false, // defer_load |
1996 NULL); // instance | 1982 NULL); // instance |
1997 tabstrip->model_->AddTabContents( | 1983 model_->AddTabContents( |
1998 contents, | 1984 contents, |
1999 -1, // index | 1985 -1, // index |
2000 false, // force_index | 1986 false, // force_index |
2001 PageTransition::TYPED, | 1987 PageTransition::TYPED, |
2002 true); // foreground | 1988 true); // foreground |
2003 break; | 1989 break; |
2004 } | 1990 } |
2005 default: | 1991 default: |
2006 NOTREACHED() << "Got click on new tab button with unhandled mouse " | 1992 NOTREACHED() << "Got click on new tab button with unhandled mouse " |
2007 << "button " << mouse_button; | 1993 << "button " << mouse_button; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2041 GetTabAt(tabs_to_paint[i])->PaintFavIconArea(event); | 2027 GetTabAt(tabs_to_paint[i])->PaintFavIconArea(event); |
2042 } | 2028 } |
2043 | 2029 |
2044 CustomDrawButton* TabStripGtk::MakeNewTabButton() { | 2030 CustomDrawButton* TabStripGtk::MakeNewTabButton() { |
2045 CustomDrawButton* button = new CustomDrawButton(IDR_NEWTAB_BUTTON, | 2031 CustomDrawButton* button = new CustomDrawButton(IDR_NEWTAB_BUTTON, |
2046 IDR_NEWTAB_BUTTON_P, IDR_NEWTAB_BUTTON_H, 0); | 2032 IDR_NEWTAB_BUTTON_P, IDR_NEWTAB_BUTTON_H, 0); |
2047 | 2033 |
2048 // Let the middle mouse button initiate clicks as well. | 2034 // Let the middle mouse button initiate clicks as well. |
2049 gtk_util::SetButtonTriggersNavigation(button->widget()); | 2035 gtk_util::SetButtonTriggersNavigation(button->widget()); |
2050 g_signal_connect(button->widget(), "clicked", | 2036 g_signal_connect(button->widget(), "clicked", |
2051 G_CALLBACK(OnNewTabClicked), this); | 2037 G_CALLBACK(OnNewTabClickedThunk), this); |
2052 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); | 2038 GTK_WIDGET_UNSET_FLAGS(button->widget(), GTK_CAN_FOCUS); |
2053 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); | 2039 gtk_fixed_put(GTK_FIXED(tabstrip_.get()), button->widget(), 0, 0); |
2054 | 2040 |
2055 return button; | 2041 return button; |
2056 } | 2042 } |
OLD | NEW |