172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <cairo/cairo.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gdk/gdkx.h> 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <gtk/gtk.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <cstdarg> 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/environment.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/linux_util.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/nix/xdg_util.h" 19513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/string_number_conversions.h" 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete.h" 224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/autocomplete/autocomplete_classifier.h" 23513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/autocomplete/autocomplete_match.h" 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h" 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/cairo_cached_surface.h" 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/gtk_theme_service.h" 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/disposition_utils.h" 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/renderer_preferences.h" 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h" 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkBitmap.h" 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/skia/include/core/SkColor.h" 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/x/x11_util.h" 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h" 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS) 434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/chromeos/frame/browser_view.h" 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/native_dialog_window.h" 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/window/window.h" 464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#else 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/browser_window_gtk.h" 484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing WebKit::WebDragOperationsMask; 51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing WebKit::WebDragOperation; 52731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing WebKit::WebDragOperationNone; 53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing WebKit::WebDragOperationCopy; 54731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing WebKit::WebDragOperationLink; 55731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing WebKit::WebDragOperationMove; 56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(GOOGLE_CHROME_BUILD) 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char* kIconName = "google-chrome"; 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char* kIconName = "chromium-browser"; 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kBoldLabelMarkup[] = "<span weight='bold'>%s</span>"; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Callback used in RemoveAllChildren. 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RemoveWidget(GtkWidget* widget, gpointer container) { 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_remove(GTK_CONTAINER(container), widget); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These two functions are copped almost directly from gtk core. The only 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// difference is that they accept middle clicks. 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean OnMouseButtonPressed(GtkWidget* widget, GdkEventButton* event, 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer userdata) { 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event->type == GDK_BUTTON_PRESS) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (gtk_button_get_focus_on_click(GTK_BUTTON(widget)) && 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !GTK_WIDGET_HAS_FOCUS(widget)) { 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_grab_focus(widget); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint button_mask = GPOINTER_TO_INT(userdata); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (button_mask & (1 << event->button)) 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_button_pressed(GTK_BUTTON(widget)); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean OnMouseButtonReleased(GtkWidget* widget, GdkEventButton* event, 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer userdata) { 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint button_mask = GPOINTER_TO_INT(userdata); 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (button_mask && (1 << event->button)) 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_button_released(GTK_BUTTON(widget)); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Returns the approximate number of characters that can horizontally fit in 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// |pixel_width| pixels. 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint GetCharacterWidthForPixels(GtkWidget* widget, int pixel_width) { 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(GTK_WIDGET_REALIZED(widget)) 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " widget must be realized to compute font metrics correctly"; 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PangoContext* context = gtk_widget_create_pango_context(widget); 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PangoFontMetrics* metrics = pango_context_get_metrics(context, 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch widget->style->font_desc, pango_context_get_language(context)); 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // This technique (max of char and digit widths) matches the code in 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // gtklabel.c. 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int char_width = pixel_width * PANGO_SCALE / 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::max(pango_font_metrics_get_approximate_char_width(metrics), 113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pango_font_metrics_get_approximate_digit_width(metrics)); 114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pango_font_metrics_unref(metrics); 116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch g_object_unref(context); 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return char_width; 119513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid OnLabelRealize(GtkWidget* label, gpointer pixel_width) { 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_label_set_width_chars( 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GTK_LABEL(label), 124513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GetCharacterWidthForPixels(label,GPOINTER_TO_INT(pixel_width))); 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Ownership of |icon_list| is passed to the caller. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGList* GetIconList() { 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GList* icon_list = NULL; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch icon_list = g_list_append(icon_list, rb.GetPixbufNamed(IDR_PRODUCT_ICON_32)); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch icon_list = g_list_append(icon_list, rb.GetPixbufNamed(IDR_PRODUCT_LOGO_16)); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return icon_list; 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Expose event handler for a container that simply suppresses the default 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// drawing and propagates the expose event to the container's children. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean PaintNoBackground(GtkWidget* widget, 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event, 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gpointer unused) { 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GList* children = gtk_container_get_children(GTK_CONTAINER(widget)); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (GList* item = children; item; item = item->next) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_propagate_expose(GTK_CONTAINER(widget), 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(item->data), 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_list_free(children); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#if defined(OS_CHROMEOS) 1534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTabContents* GetBrowserWindowSelectedTabContents(BrowserWindow* window) { 1554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch chromeos::BrowserView* browser_view = static_cast<chromeos::BrowserView*>( 1564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch window); 1574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return browser_view->GetSelectedTabContents(); 1584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 1594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochGtkWidget* GetBrowserWindowFocusedWidget(BrowserWindow* window) { 1614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch gfx::NativeView widget = gtk_window_get_focus(window->GetNativeHandle()); 1624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (widget == NULL) { 1644a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch chromeos::BrowserView* browser_view = static_cast<chromeos::BrowserView*>( 1654a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch window); 1664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch widget = browser_view->saved_focused_widget(); 1674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 1684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return widget; 1704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 1714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#else 1734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTabContents* GetBrowserWindowSelectedTabContents(BrowserWindow* window) { 1754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>( 1764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch window); 1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return browser_window->browser()->GetSelectedTabContents(); 1784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochGtkWidget* GetBrowserWindowFocusedWidget(BrowserWindow* window) { 1814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return gtk_window_get_focus(window->GetNativeHandle()); 1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 1834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif 1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace event_utils { 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWindowOpenDisposition DispositionFromEventFlags(guint event_flags) { 19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return disposition_utils::DispositionFromClick( 19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event_flags & GDK_BUTTON2_MASK, 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event_flags & GDK_MOD1_MASK, 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event_flags & GDK_CONTROL_MASK, 19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event_flags & GDK_META_MASK, 19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen event_flags & GDK_SHIFT_MASK); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace event_utils 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace gtk_util { 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst GdkColor kGdkWhite = GDK_COLOR_RGB(0xff, 0xff, 0xff); 204513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst GdkColor kGdkGray = GDK_COLOR_RGB(0x7f, 0x7f, 0x7f); 205513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst GdkColor kGdkBlack = GDK_COLOR_RGB(0x00, 0x00, 0x00); 206513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst GdkColor kGdkGreen = GDK_COLOR_RGB(0x00, 0xff, 0x00); 207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* CreateLabeledControlsGroup(std::vector<GtkWidget*>* labels, 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* text, ...) { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch va_list ap; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch va_start(ap, text); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* table = gtk_table_new(0, 2, FALSE); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_table_set_col_spacing(GTK_TABLE(table), 0, kLabelSpacing); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_table_set_row_spacings(GTK_TABLE(table), kControlSpacing); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (guint row = 0; text; ++row) { 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_table_resize(GTK_TABLE(table), row + 1, 2); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* control = va_arg(ap, GtkWidget*); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* label = gtk_label_new(text); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (labels) 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch labels->push_back(label); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_table_attach(GTK_TABLE(table), label, 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 1, row, row + 1, 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_FILL, GTK_FILL, 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0); 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_table_attach_defaults(GTK_TABLE(table), control, 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, 2, row, row + 1); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text = va_arg(ap, const char*); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch va_end(ap); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return table; 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* CreateGtkBorderBin(GtkWidget* child, const GdkColor* color, 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int top, int bottom, int left, int right) { 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use a GtkEventBox to get the background painted. However, we can't just 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // use a container border, since it won't paint there. Use an alignment 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // inside to get the sizes exactly of how we want the border painted. 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* ebox = gtk_event_box_new(); 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (color) 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(ebox, GTK_STATE_NORMAL, color); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), top, bottom, left, right); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(alignment), child); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(ebox), alignment); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ebox; 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* LeftAlignMisc(GtkWidget* misc) { 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_misc_set_alignment(GTK_MISC(misc), 0, 0.5); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return misc; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* CreateBoldLabel(const std::string& text) { 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* label = gtk_label_new(NULL); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch char* markup = g_markup_printf_escaped(kBoldLabelMarkup, text.c_str()); 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_label_set_markup(GTK_LABEL(label), markup); 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_free(markup); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return LeftAlignMisc(label); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 266513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid GetWidgetSizeFromCharacters( 267513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GtkWidget* widget, double width_chars, double height_lines, 268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int* width, int* height) { 269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(GTK_WIDGET_REALIZED(widget)) 270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " widget must be realized to compute font metrics correctly"; 271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PangoContext* context = gtk_widget_create_pango_context(widget); 272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch PangoFontMetrics* metrics = pango_context_get_metrics(context, 273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch widget->style->font_desc, pango_context_get_language(context)); 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (width) { 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *width = static_cast<int>( 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pango_font_metrics_get_approximate_char_width(metrics) * 277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch width_chars / PANGO_SCALE); 278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (height) { 280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *height = static_cast<int>( 281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (pango_font_metrics_get_ascent(metrics) + 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pango_font_metrics_get_descent(metrics)) * 283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch height_lines / PANGO_SCALE); 284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pango_font_metrics_unref(metrics); 286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch g_object_unref(context); 287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 289513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid GetWidgetSizeFromResources( 290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GtkWidget* widget, int width_chars, int height_lines, 291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int* width, int* height) { 292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(GTK_WIDGET_REALIZED(widget)) 293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch << " widget must be realized to compute font metrics correctly"; 294513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 295513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch double chars = 0; 296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (width) 297513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::StringToDouble(l10n_util::GetStringUTF8(width_chars), &chars); 298513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 299513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch double lines = 0; 300513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (height) 301513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::StringToDouble(l10n_util::GetStringUTF8(height_lines), &lines); 302513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 303513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GetWidgetSizeFromCharacters(widget, chars, lines, width, height); 304513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetWindowSizeFromResources(GtkWindow* window, 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int width_id, int height_id, bool resizable) { 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int width = -1; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int height = -1; 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::GetWidgetSizeFromResources(GTK_WIDGET(window), width_id, height_id, 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (width_id != -1) ? &width : NULL, 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (height_id != -1) ? &height : NULL); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (resizable) { 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_default_size(window, width, height); 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For a non-resizable window, GTK tries to snap the window size 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to the minimum size around the content. We use the sizes in 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the resources to set *minimum* window size to allow windows 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // with long titles to be wide enough to display their titles. 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // But if GTK wants to make the window *wider* due to very wide 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // controls, we should allow that too, so be careful to pick the 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // wider of the resources size and the natural window size. 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(GTK_BIN(window)->child); 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkRequisition requisition; 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_size_request(GTK_WIDGET(window), &requisition); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request( 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(window), 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width == -1 ? -1 : std::max(width, requisition.width), 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch height == -1 ? -1 : std::max(height, requisition.height)); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_resizable(window, resizable ? TRUE : FALSE); 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CenterOverWindow(GtkWindow* window, GtkWindow* parent) { 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect frame_bounds = gtk_util::GetWidgetScreenBounds(GTK_WIDGET(parent)); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point origin = frame_bounds.origin(); 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size size = gtk_util::GetWidgetSize(GTK_WIDGET(window)); 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin.Offset( 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (frame_bounds.width() - size.width()) / 2, 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (frame_bounds.height() - size.height()) / 2); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Prevent moving window out of monitor bounds. 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkScreen* screen = gtk_window_get_screen(parent); 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (screen) { 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It would be better to check against workarea for given monitor 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but getting workarea for particular monitor is tricky. 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint monitor = gdk_screen_get_monitor_at_window(screen, 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(parent)->window); 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle rect; 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_screen_get_monitor_geometry(screen, monitor, &rect); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check the right bottom corner. 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (origin.x() > rect.x + rect.width - size.width()) 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin.set_x(rect.x + rect.width - size.width()); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (origin.y() > rect.y + rect.height - size.height()) 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin.set_y(rect.y + rect.height - size.height()); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check the left top corner. 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (origin.x() < rect.x) 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin.set_x(rect.x); 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (origin.y() < rect.y) 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch origin.set_y(rect.y); 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_move(window, origin.x(), origin.y()); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Move to user expected desktop if window is already visible. 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GTK_WIDGET(window)->window) { 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::ChangeWindowDesktop( 37372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::GetX11WindowFromGtkWidget(GTK_WIDGET(window)), 37472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::GetX11WindowFromGtkWidget(GTK_WIDGET(parent))); 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MakeAppModalWindowGroup() { 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if GTK_CHECK_VERSION(2, 14, 0) 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Older versions of GTK+ don't give us gtk_window_group_list() which is what 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we need to add current non-browser modal dialogs to the list. If 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we have 2.14+ we can do things the correct way. 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* window_group = gtk_window_group_new(); 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserList::const_iterator it = BrowserList::begin(); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != BrowserList::end(); ++it) { 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // List all windows in this current group 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* old_group = 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_group((*it)->window()->GetNativeHandle()); 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GList* all_windows = gtk_window_group_list_windows(old_group); 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (GList* window = all_windows; window; window = window->next) { 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_group_add_window(window_group, GTK_WINDOW(window->data)); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_list_free(all_windows); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(window_group); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Otherwise just grab all browser windows and be slightly broken. 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* window_group = gtk_window_group_new(); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserList::const_iterator it = BrowserList::begin(); 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != BrowserList::end(); ++it) { 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_group_add_window(window_group, 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*it)->window()->GetNativeHandle()); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(window_group); 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AppModalDismissedUngroupWindows() { 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if GTK_CHECK_VERSION(2, 14, 0) 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (BrowserList::begin() != BrowserList::end()) { 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GtkWindow*> transient_windows; 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All windows should be part of one big modal group right now. 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* window_group = gtk_window_get_group( 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*BrowserList::begin())->window()->GetNativeHandle()); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GList* windows = gtk_window_group_list_windows(window_group); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (GList* item = windows; item; item = item->next) { 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindow* window = GTK_WINDOW(item->data); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindow* transient_for = gtk_window_get_transient_for(window); 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (transient_for) { 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch transient_windows.push_back(window); 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* window_group = gtk_window_group_new(); 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_group_add_window(window_group, window); 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(window_group); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Put each transient window in the same group as its transient parent. 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<GtkWindow*>::iterator it = transient_windows.begin(); 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != transient_windows.end(); ++it) { 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindow* transient_parent = gtk_window_get_transient_for(*it); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* group = gtk_window_get_group(transient_parent); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_group_add_window(group, *it); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is slightly broken in the case where a different window had a dialog, 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but its the best we can do since we don't have newer gtk stuff. 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (BrowserList::const_iterator it = BrowserList::begin(); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it != BrowserList::end(); ++it) { 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindowGroup* window_group = gtk_window_group_new(); 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_group_add_window(window_group, 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*it)->window()->GetNativeHandle()); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(window_group); 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RemoveAllChildren(GtkWidget* container) { 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_foreach(GTK_CONTAINER(container), RemoveWidget, container); 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ForceFontSizePixels(GtkWidget* widget, double size_pixels) { 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkStyle* style = widget->style; 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PangoFontDescription* font_desc = style->font_desc; 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pango_font_description_set_absolute_size sets the font size in device 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // units, which for us is pixels. 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pango_font_description_set_absolute_size(font_desc, 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PANGO_SCALE * size_pixels); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_font(widget, font_desc); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid UndoForceFontSize(GtkWidget* widget) { 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_font(widget, NULL); 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Point GetWidgetScreenPosition(GtkWidget* widget) { 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!widget->window) { 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Must only be called on realized widgets."; 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Point(0, 0); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x, y; 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_get_origin(widget->window, &x, &y); 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (GTK_WIDGET_NO_WINDOW(widget)) { 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch x += widget->allocation.x; 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch y += widget->allocation.y; 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Point(x, y); 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect GetWidgetScreenBounds(GtkWidget* widget) { 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point position = GetWidgetScreenPosition(widget); 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Rect(position.x(), position.y(), 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget->allocation.width, widget->allocation.height); 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Size GetWidgetSize(GtkWidget* widget) { 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkRequisition size; 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_size_request(widget, &size); 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Size(size.width, size.height); 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConvertWidgetPointToScreen(GtkWidget* widget, gfx::Point* p) { 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(widget); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(p); 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point position = GetWidgetScreenPosition(widget); 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch p->SetPoint(p->x() + position.x(), p->y() + position.y()); 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InitRCStyles() { 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const char kRCText[] = 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make our dialogs styled like the GNOME HIG. 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(evanm): content-area-spacing was introduced in a later 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // version of GTK, so we need to set that manually on all dialogs. 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Perhaps it would make sense to have a shared FixupDialog() function. 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "style \"gnome-dialog\" {\n" 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " xthickness = 12\n" 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::action-area-border = 0\n" 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::button-spacing = 6\n" 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::content-area-spacing = 18\n" 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::content-area-border = 12\n" 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "}\n" 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note we set it at the "application" priority, so users can override. 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "widget \"GtkDialog\" style : application \"gnome-dialog\"\n" 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make our about dialog special, so the image is flush with the edge. 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "style \"about-dialog\" {\n" 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::action-area-border = 12\n" 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::button-spacing = 6\n" 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::content-area-spacing = 18\n" 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " GtkDialog::content-area-border = 0\n" 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "}\n" 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "widget \"about-dialog\" style : application \"about-dialog\"\n"; 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_rc_parse_string(kRCText); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* CenterWidgetInHBox(GtkWidget* hbox, GtkWidget* widget, 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool pack_at_end, int padding) { 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* centering_vbox = gtk_vbox_new(FALSE, 0); 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(centering_vbox), widget, TRUE, FALSE, 0); 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (pack_at_end) 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, padding); 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(hbox), centering_vbox, FALSE, FALSE, padding); 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return centering_vbox; 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool IsScreenComposited() { 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkScreen* screen = gdk_screen_get_default(); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gdk_screen_is_composited(screen) == TRUE; 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate) { 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<XID> stack; 55572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) { 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to old school enumeration of all X windows. Some WMs parent 'top-level' 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // windows in unnamed actual top-level windows (ion WM), so extend the 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // search depth to all children of top-level windows. 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kMaxSearchDepth = 1; 56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::EnumerateAllWindows(delegate, kMaxSearchDepth); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<XID>::iterator iter; 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (iter = stack.begin(); iter != stack.end(); iter++) { 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delegate->ShouldStopIterating(*iter)) 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetButtonClickableByMouseButtons(GtkWidget* button, 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool left, bool middle, bool right) { 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint button_mask = 0; 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (left) 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch button_mask |= 1 << 1; 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (middle) 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch button_mask |= 1 << 2; 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (right) 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch button_mask |= 1 << 3; 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* userdata = GINT_TO_POINTER(button_mask); 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(button, "button-press-event", 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnMouseButtonPressed), userdata); 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(button, "button-release-event", 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnMouseButtonReleased), userdata); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetButtonTriggersNavigation(GtkWidget* button) { 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetButtonClickableByMouseButtons(button, true, true, false); 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint MirroredLeftPointForRect(GtkWidget* widget, const gfx::Rect& bounds) { 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!base::i18n::IsRTL()) 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return bounds.x(); 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return widget->allocation.width - bounds.x() - bounds.width(); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint MirroredXCoordinate(GtkWidget* widget, int x) { 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (base::i18n::IsRTL()) 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return widget->allocation.width - x; 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return x; 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WidgetContainsCursor(GtkWidget* widget) { 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x = 0; 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint y = 0; 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_get_pointer(widget, &x, &y); 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return WidgetBounds(widget).Contains(x, y); 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetWindowIcon(GtkWindow* window) { 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GList* icon_list = GetIconList(); 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_icon_list(window, icon_list); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_list_free(icon_list); 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 618dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid SetDefaultWindowIcon(GtkWindow* window) { 619dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GtkIconTheme* theme = 620dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_icon_theme_get_for_screen(gtk_widget_get_screen(GTK_WIDGET(window))); 621dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 622dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (gtk_icon_theme_has_icon(theme, kIconName)) { 623dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_window_set_default_icon_name(kIconName); 624dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Sometimes the WM fails to update the icon when we tell it to. The above 625dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // line should be enough to update all existing windows, but it can fail, 626dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // e.g. with Lucid/metacity. The following line seems to fix the common 627dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // case where the first window created doesn't have an icon. 628dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_window_set_icon_name(window, kIconName); 629dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 630dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GList* icon_list = GetIconList(); 631dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_window_set_default_icon_list(icon_list); 632dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Same logic applies here. 633dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_window_set_icon_list(window, icon_list); 634dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen g_list_free(icon_list); 635dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* AddButtonToDialog(GtkWidget* dialog, const gchar* text, 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gchar* stock_id, gint response_id) { 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* button = gtk_button_new_with_label(text); 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_button_set_image(GTK_BUTTON(button), 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_image_new_from_stock(stock_id, 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_ICON_SIZE_BUTTON)); 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_dialog_add_action_widget(GTK_DIALOG(dialog), button, 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response_id); 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return button; 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* BuildDialogButton(GtkWidget* dialog, int ids_id, 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gchar* stock_id) { 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* button = gtk_button_new_with_mnemonic( 652513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gfx::ConvertAcceleratorsFromWindowsStyle( 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch l10n_util::GetStringUTF8(ids_id)).c_str()); 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_button_set_image(GTK_BUTTON(button), 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_image_new_from_stock(stock_id, 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_ICON_SIZE_BUTTON)); 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return button; 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* CreateEntryImageHBox(GtkWidget* entry, GtkWidget* image) { 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing); 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return hbox; 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetLabelColor(GtkWidget* label, const GdkColor* color) { 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_fg(label, GTK_STATE_NORMAL, color); 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, color); 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, color); 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, color); 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* IndentWidget(GtkWidget* content) { 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* content_alignment = gtk_alignment_new(0.0, 0.5, 1.0, 1.0); 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(content_alignment), 0, 0, 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::kGroupIndent, 0); 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(content_alignment), content); 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return content_alignment; 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid UpdateGtkFontSettings(RendererPreferences* prefs) { 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(prefs); 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // From http://library.gnome.org/devel/gtk/unstable/GtkSettings.html, this is 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the default value for gtk-cursor-blink-time. 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const gint kGtkDefaultCursorBlinkTime = 1200; 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint cursor_blink_time = kGtkDefaultCursorBlinkTime; 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gboolean cursor_blink = TRUE; 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint antialias = 0; 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint hinting = 0; 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gchar* hint_style = NULL; 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gchar* rgba_style = NULL; 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_get(gtk_settings_get_default(), 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-cursor-blink-time", &cursor_blink_time, 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-cursor-blink", &cursor_blink, 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-xft-antialias", &antialias, 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-xft-hinting", &hinting, 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-xft-hintstyle", &hint_style, 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-xft-rgba", &rgba_style, 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set some reasonable defaults. 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->should_antialias_text = true; 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->hinting = RENDERER_PREFERENCES_HINTING_SYSTEM_DEFAULT; 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->subpixel_rendering = 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RENDERER_PREFERENCES_SUBPIXEL_RENDERING_SYSTEM_DEFAULT; 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cursor_blink) { 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Dividing by 2*1000ms follows the WebKit GTK port and makes the blink 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frequency appear similar to the omnibox. Without this the blink is too 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // slow. 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->caret_blink_interval = cursor_blink_time / 2000.; 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->caret_blink_interval = 0; 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // g_object_get() doesn't tell us whether the properties were present or not, 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // but if they aren't (because gnome-settings-daemon isn't running), we'll get 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NULL values for the strings. 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (hint_style && rgba_style) { 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->should_antialias_text = antialias; 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (hinting == 0 || strcmp(hint_style, "hintnone") == 0) { 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->hinting = RENDERER_PREFERENCES_HINTING_NONE; 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(hint_style, "hintslight") == 0) { 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->hinting = RENDERER_PREFERENCES_HINTING_SLIGHT; 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(hint_style, "hintmedium") == 0) { 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->hinting = RENDERER_PREFERENCES_HINTING_MEDIUM; 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(hint_style, "hintfull") == 0) { 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->hinting = RENDERER_PREFERENCES_HINTING_FULL; 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (strcmp(rgba_style, "none") == 0) { 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->subpixel_rendering = RENDERER_PREFERENCES_SUBPIXEL_RENDERING_NONE; 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(rgba_style, "rgb") == 0) { 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->subpixel_rendering = RENDERER_PREFERENCES_SUBPIXEL_RENDERING_RGB; 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(rgba_style, "bgr") == 0) { 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->subpixel_rendering = RENDERER_PREFERENCES_SUBPIXEL_RENDERING_BGR; 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(rgba_style, "vrgb") == 0) { 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->subpixel_rendering = RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VRGB; 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (strcmp(rgba_style, "vbgr") == 0) { 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->subpixel_rendering = RENDERER_PREFERENCES_SUBPIXEL_RENDERING_VBGR; 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (hint_style) 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_free(hint_style); 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rgba_style) 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_free(rgba_style); 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Point ScreenPoint(GtkWidget* widget) { 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int x, y; 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_display_get_pointer(gtk_widget_get_display(widget), NULL, &x, &y, 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Point(x, y); 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Point ClientPoint(GtkWidget* widget) { 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int x, y; 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_get_pointer(widget, &x, &y); 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Point(x, y); 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGdkPoint MakeBidiGdkPoint(gint x, gint y, gint width, bool ltr) { 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkPoint point = {ltr ? x : width - x, y}; 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return point; 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DrawTextEntryBackground(GtkWidget* offscreen_entry, 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* widget_to_draw_on, 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle* dirty_rec, 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle* rec) { 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkStyle* gtk_owned_style = gtk_rc_get_style(offscreen_entry); 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GTK owns the above and we're going to have to make our own copy of it 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that we can edit. 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkStyle* our_style = gtk_style_copy(gtk_owned_style); 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch our_style = gtk_style_attach(our_style, widget_to_draw_on->window); 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(erg): Draw the focus ring if appropriate... 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're using GTK rendering; draw a GTK entry widget onto the background. 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_paint_shadow(our_style, widget_to_draw_on->window, 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_STATE_NORMAL, GTK_SHADOW_IN, dirty_rec, 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch widget_to_draw_on, "entry", 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rec->x, rec->y, rec->width, rec->height); 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Draw the interior background (not all themes draw the entry background 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // above; this is a noop on themes that do). 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint xborder = our_style->xthickness; 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint yborder = our_style->ythickness; 79421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen gint width = rec->width - 2 * xborder; 79521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen gint height = rec->height - 2 * yborder; 79621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (width > 0 && height > 0) { 79721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen gtk_paint_flat_box(our_style, widget_to_draw_on->window, 79821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GTK_STATE_NORMAL, GTK_SHADOW_NONE, dirty_rec, 79921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen widget_to_draw_on, "entry_bg", 80021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen rec->x + xborder, rec->y + yborder, 80121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen width, height); 80221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 8044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch gtk_style_detach(our_style); 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(our_style); 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid DrawThemedToolbarBackground(GtkWidget* widget, 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_t* cr, 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event, 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Point& tabstrip_origin, 812ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* theme_service) { 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fill the entire region with the toolbar color. 814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GdkColor color = theme_service->GetGdkColor( 815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ThemeService::COLOR_TOOLBAR); 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_cairo_set_source_color(cr, &color); 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The toolbar is supposed to blend in with the active tab, so we have to pass 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // coordinates for the IDR_THEME_TOOLBAR bitmap relative to the top of the 821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // tab strip. 822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CairoCachedSurface* background = theme_service->GetSurfaceNamed( 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_THEME_TOOLBAR, widget); 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch background->SetSource(cr, tabstrip_origin.x(), tabstrip_origin.y()); 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We tile the toolbar background in both directions. 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_origin.x(), 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_origin.y(), 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event->area.x + event->area.width - tabstrip_origin.x(), 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event->area.y + event->area.height - tabstrip_origin.y()); 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGdkColor AverageColors(GdkColor color_one, GdkColor color_two) { 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkColor average_color; 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch average_color.pixel = 0; 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch average_color.red = (color_one.red + color_two.red) / 2; 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch average_color.green = (color_one.green + color_two.green) / 2; 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch average_color.blue = (color_one.blue + color_two.blue) / 2; 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return average_color; 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetAlwaysShowImage(GtkWidget* image_menu_item) { 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Compile time check: if it's available, just use the API. 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GTK_CHECK_VERSION is TRUE if the passed version is compatible. 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if GTK_CHECK_VERSION(2, 16, 1) 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_image_menu_item_set_always_show_image( 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_IMAGE_MENU_ITEM(image_menu_item), TRUE); 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Run time check: if the API is not available, set the property manually. 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This will still only work with GTK 2.16+ as the property doesn't exist 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in earlier versions. 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_check_version() returns NULL if the passed version is compatible. 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gtk_check_version(2, 16, 1)) { 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GValue true_value = { 0 }; 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_init(&true_value, G_TYPE_BOOLEAN); 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_value_set_boolean(&true_value, TRUE); 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_set_property(G_OBJECT(image_menu_item), "always-show-image", 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &true_value); 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect GetWidgetRectRelativeToToplevel(GtkWidget* widget) { 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(GTK_WIDGET_REALIZED(widget)); 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* toplevel = gtk_widget_get_toplevel(widget); 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(toplevel); 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(GTK_WIDGET_REALIZED(toplevel)); 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x = 0, y = 0; 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_translate_coordinates(widget, 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toplevel, 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 0, 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &x, &y); 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Rect(x, y, widget->allocation.width, widget->allocation.height); 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SuppressDefaultPainting(GtkWidget* container) { 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(container, "expose-event", 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(PaintNoBackground), NULL); 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWindowOpenDisposition DispositionForCurrentButtonPressEvent() { 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEvent* event = gtk_get_current_event(); 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!event) { 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NEW_FOREGROUND_TAB; 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint state = event->button.state; 893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_event_free(event); 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return event_utils::DispositionFromEventFlags(state); 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GrabAllInput(GtkWidget* widget) { 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint time = gtk_get_current_event_time(); 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GTK_WIDGET_VISIBLE(widget)) 901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gdk_pointer_grab(widget->window, TRUE, 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventMask(GDK_BUTTON_PRESS_MASK | 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_BUTTON_RELEASE_MASK | 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_ENTER_NOTIFY_MASK | 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_LEAVE_NOTIFY_MASK | 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_POINTER_MOTION_MASK), 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, NULL, time) == 0) { 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gdk_keyboard_grab(widget->window, TRUE, time) == 0) { 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_display_pointer_ungrab(gdk_drawable_get_display(widget->window), time); 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_grab_add(widget); 919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect WidgetBounds(GtkWidget* widget) { 923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To quote the gtk docs: 924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Widget coordinates are a bit odd; for historical reasons, they are 926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // defined as widget->window coordinates for widgets that are not 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GTK_NO_WINDOW widgets, and are relative to widget->allocation.x, 928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // widget->allocation.y for widgets that are GTK_NO_WINDOW widgets. 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // So the base is always (0,0). 931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Rect(0, 0, widget->allocation.width, widget->allocation.height); 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SetWMLastUserActionTime(GtkWindow* window) { 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_x11_window_set_user_time(GTK_WIDGET(window)->window, XTimeNow()); 936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochguint32 XTimeNow() { 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct timespec ts; 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch clock_gettime(CLOCK_MONOTONIC, &ts); 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool URLFromPrimarySelection(Profile* profile, GURL* url) { 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(clipboard); 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gchar* selection_text = gtk_clipboard_wait_for_text(clipboard); 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!selection_text) 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Use autocomplete to clean up the text, going so far as to turn it into 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a search query if necessary. 9534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch AutocompleteMatch match; 95472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen profile->GetAutocompleteClassifier()->Classify(UTF8ToUTF16(selection_text), 95572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16(), false, &match, NULL); 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_free(selection_text); 9574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!match.destination_url.is_valid()) 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch *url = match.destination_url; 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool AddWindowAlphaChannel(GtkWidget* window) { 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkScreen* screen = gtk_widget_get_screen(window); 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen); 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rgba) 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_colormap(window, rgba); 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return rgba; 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid GetTextColors(GdkColor* normal_base, 9743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkColor* selected_base, 9753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkColor* normal_text, 9763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkColor* selected_text) { 9773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GtkWidget* fake_entry = gtk_entry_new(); 9783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GtkStyle* style = gtk_rc_get_style(fake_entry); 9793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (normal_base) 9813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *normal_base = style->base[GTK_STATE_NORMAL]; 9823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (selected_base) 9833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *selected_base = style->base[GTK_STATE_SELECTED]; 9843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (normal_text) 9853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *normal_text = style->text[GTK_STATE_NORMAL]; 9863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (selected_text) 9873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *selected_text = style->text[GTK_STATE_SELECTED]; 9883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick g_object_ref_sink(fake_entry); 9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick g_object_unref(fake_entry); 9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS) 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenGtkWindow* GetLastActiveBrowserWindow() { 99672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (Browser* b = BrowserList::GetLastActive()) { 99772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (b->type() != Browser::TYPE_NORMAL) { 99872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen b = BrowserList::FindBrowserWithType(b->profile(), 99972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Browser::TYPE_NORMAL, 100072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen true); 100172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 100272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 100372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (b) 100472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return GTK_WINDOW(b->window()->GetNativeHandle()); 100572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 100672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 100772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 100872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 100972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1010dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenint GetNativeDialogFlags(GtkWindow* dialog) { 1011dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int flags = chromeos::DIALOG_FLAG_DEFAULT; 1012dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1013dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (gtk_window_get_resizable(dialog)) 1014dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen flags |= chromeos::DIALOG_FLAG_RESIZEABLE; 1015dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (gtk_window_get_modal(dialog)) 1016dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen flags |= chromeos::DIALOG_FLAG_MODAL; 1017dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1018dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return flags; 1019dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 1020dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWindow* GetDialogTransientParent(GtkWindow* dialog) { 1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindow* parent = gtk_window_get_transient_for(dialog); 1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parent) 102472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen parent = GetLastActiveBrowserWindow(); 1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return parent; 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShowDialog(GtkWidget* dialog) { 1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure all controls are visible so that we get correct size. 1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(GTK_DIALOG(dialog)->vbox); 1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get dialog window size. 1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint width = 0; 1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint height = 0; 1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); 1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chromeos::ShowNativeDialog(GetDialogTransientParent(GTK_WINDOW(dialog)), 1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog, 1040dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GetNativeDialogFlags(GTK_WINDOW(dialog)), 1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size(width, height), 1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size()); 1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShowDialogWithLocalizedSize(GtkWidget* dialog, 1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int width_id, 1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int height_id, 1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool resizeable) { 1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int width = (width_id == -1) ? 0 : 1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::Window::GetLocalizedContentsWidth(width_id); 1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int height = (height_id == -1) ? 0 : 1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::Window::GetLocalizedContentsHeight(height_id); 1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chromeos::ShowNativeDialog(GetDialogTransientParent(GTK_WINDOW(dialog)), 1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog, 1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch resizeable ? chromeos::DIALOG_FLAG_RESIZEABLE : 1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chromeos::DIALOG_FLAG_DEFAULT, 1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size(width, height), 1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size()); 1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1062dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ShowDialogWithMinLocalizedWidth(GtkWidget* dialog, 1063dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int width_id) { 1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int width = (width_id == -1) ? 0 : 1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch views::Window::GetLocalizedContentsWidth(width_id); 1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chromeos::ShowNativeDialog(GetDialogTransientParent(GTK_WINDOW(dialog)), 1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch dialog, 1069dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GetNativeDialogFlags(GTK_WINDOW(dialog)), 1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size(), 1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Size(width, 0)); 1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PresentWindow(GtkWidget* window, int timestamp) { 1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWindow* host_window = chromeos::GetNativeDialogWindow(window); 1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!host_window) 1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_window = GTK_WINDOW(window); 1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (timestamp) 1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_present_with_time(host_window, timestamp); 1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_present(host_window); 1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWindow* GetDialogWindow(GtkWidget* dialog) { 1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return chromeos::GetNativeDialogWindow(dialog); 1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect GetDialogBounds(GtkWidget* dialog) { 1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return chromeos::GetNativeDialogContentsBounds(dialog); 1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 1093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShowDialog(GtkWidget* dialog) { 1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(dialog); 1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ShowDialogWithLocalizedSize(GtkWidget* dialog, 1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int width_id, 1100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int height_id, 1101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool resizeable) { 1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_realize(dialog); 1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetWindowSizeFromResources(GTK_WINDOW(dialog), 1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width_id, 1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch height_id, 1106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch resizeable); 1107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(dialog); 1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ShowDialogWithMinLocalizedWidth(GtkWidget* dialog, 1111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int width_id) { 1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(dialog); 1113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Suggest a minimum size. 1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint width; 1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkRequisition req; 1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_size_request(dialog, &req); 1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::GetWidgetSizeFromResources(dialog, width_id, 0, &width, NULL); 1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (width > req.width) 1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(dialog, width, -1); 1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid PresentWindow(GtkWidget* window, int timestamp) { 1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (timestamp) 1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_present_with_time(GTK_WINDOW(window), timestamp); 1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_present(GTK_WINDOW(window)); 1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWindow* GetDialogWindow(GtkWidget* dialog) { 1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GTK_WINDOW(dialog); 1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect GetDialogBounds(GtkWidget* dialog) { 1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x = 0, y = 0, width = 1, height = 1; 1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_position(GTK_WINDOW(dialog), &x, &y); 1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_size(GTK_WINDOW(dialog), &width, &height); 1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Rect(x, y, width, height); 1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 11414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstring16 GetStockPreferencesMenuLabel() { 11453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GtkStockItem stock_item; 11463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 preferences; 11473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (gtk_stock_lookup(GTK_STOCK_PREFERENCES, &stock_item)) { 11483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char16 kUnderscore[] = { '_', 0 }; 11493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RemoveChars(UTF8ToUTF16(stock_item.label), kUnderscore, &preferences); 11503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 11513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return preferences; 11523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool IsWidgetAncestryVisible(GtkWidget* widget) { 11553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GtkWidget* parent = widget; 11563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while (parent && GTK_WIDGET_VISIBLE(parent)) 11573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parent = parent->parent; 11583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return !parent; 11593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SetLabelWidth(GtkWidget* label, int pixel_width) { 11623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 116372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 11643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Do the simple thing in LTR because the bug only affects right-aligned 11663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // text. Also, when using the workaround, the label tries to maintain 11673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // uniform line-length, which we don't really want. 11683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (gtk_widget_get_direction(label) == GTK_TEXT_DIR_LTR) { 11693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_widget_set_size_request(label, pixel_width, -1); 11703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 11713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The label has to be realized before we can adjust its width. 11723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (GTK_WIDGET_REALIZED(label)) { 11733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OnLabelRealize(label, GINT_TO_POINTER(pixel_width)); 11743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 11753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick g_signal_connect(label, "realize", G_CALLBACK(OnLabelRealize), 11763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GINT_TO_POINTER(pixel_width)); 11773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 11783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 11793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 11813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid InitLabelSizeRequestAndEllipsizeMode(GtkWidget* label) { 11823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GtkRequisition size; 11833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_NONE); 11843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_widget_set_size_request(label, -1, -1); 11853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_widget_size_request(label, &size); 11863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_widget_set_size_request(label, size.width, size.height); 11873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); 11883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1190731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickGdkDragAction WebDragOpToGdkDragAction(WebDragOperationsMask op) { 1191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GdkDragAction action = static_cast<GdkDragAction>(0); 1192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (op & WebDragOperationCopy) 1193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick action = static_cast<GdkDragAction>(action | GDK_ACTION_COPY); 1194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (op & WebDragOperationLink) 1195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick action = static_cast<GdkDragAction>(action | GDK_ACTION_LINK); 1196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (op & WebDragOperationMove) 1197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick action = static_cast<GdkDragAction>(action | GDK_ACTION_MOVE); 1198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return action; 1199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1201731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickWebDragOperationsMask GdkDragActionToWebDragOp(GdkDragAction action) { 1202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick WebDragOperationsMask op = WebDragOperationNone; 1203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (action & GDK_ACTION_COPY) 1204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick op = static_cast<WebDragOperationsMask>(op | WebDragOperationCopy); 1205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (action & GDK_ACTION_LINK) 1206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick op = static_cast<WebDragOperationsMask>(op | WebDragOperationLink); 1207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (action & GDK_ACTION_MOVE) 1208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick op = static_cast<WebDragOperationsMask>(op | WebDragOperationMove); 1209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return op; 1210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1211731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1212513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid ApplyMessageDialogQuirks(GtkWidget* dialog) { 1213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (gtk_window_get_modal(GTK_WINDOW(dialog))) { 1214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Work around a KDE 3 window manager bug. 1215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_ptr<base::Environment> env(base::Environment::Create()); 1216513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (base::nix::DESKTOP_ENVIRONMENT_KDE3 == 1217513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::nix::GetDesktopEnvironment(env.get())) 1218513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE); 1219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 1220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 12224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// Performs Cut/Copy/Paste operation on the |window|. 12234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// If the current render view is focused, then just call the specified |method| 12244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// against the current render view host, otherwise emit the specified |signal| 12254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// against the focused widget. 12264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// TODO(suzhe): This approach does not work for plugins. 12274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DoCutCopyPaste(BrowserWindow* window, 12284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch void (RenderViewHost::*method)(), 12294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const char* signal) { 12304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch GtkWidget* widget = GetBrowserWindowFocusedWidget(window); 12314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (widget == NULL) 12324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return; // Do nothing if no focused widget. 12334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 12344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch TabContents* current_tab = GetBrowserWindowSelectedTabContents(window); 12354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (current_tab && widget == current_tab->GetContentNativeView()) { 12364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch (current_tab->render_view_host()->*method)(); 12374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else { 12384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch guint id; 12394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if ((id = g_signal_lookup(signal, G_OBJECT_TYPE(widget))) != 0) 12404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch g_signal_emit(widget, id, 0); 12414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 12424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 12434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 12444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DoCut(BrowserWindow* window) { 12454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DoCutCopyPaste(window, &RenderViewHost::Cut, "cut-clipboard"); 12464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 12474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 12484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DoCopy(BrowserWindow* window) { 12494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DoCutCopyPaste(window, &RenderViewHost::Copy, "copy-clipboard"); 12504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 12514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 12524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid DoPaste(BrowserWindow* window) { 12534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DoCutCopyPaste(window, &RenderViewHost::Paste, "paste-clipboard"); 12544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 12554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace gtk_util 1257