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/browser_window_gtk.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gdk/gdkkeysyms.h> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <dlfcn.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/base_paths.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/environment.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/i18n/file_util_icu.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/nix/xdg_util.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/app/chrome_command_ids.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/autocomplete/autocomplete_edit_view.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_utils.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_window.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_item_model.h" 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_manager.h" 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/page_info_window.h" 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h" 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h" 3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tabs/tab_strip_model.h" 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/themes/theme_service.h" 3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" 394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser_dialogs.h" 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h" 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/find_bar/find_bar_controller.h" 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/find_bar/find_tab_helper.h" 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/about_chrome_dialog.h" 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/accelerators_gtk.h" 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h" 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/browser_titlebar.h" 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/cairo_cached_surface.h" 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/collected_cookies_gtk.h" 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h" 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/download/download_in_progress_dialog_gtk.h" 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/download/download_shelf_gtk.h" 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/edit_search_engine_dialog.h" 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/find_bar_gtk.h" 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.h" 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/global_menu_bar.h" 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_floating_container.h" 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/gtk_theme_service.h" 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h" 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/info_bubble_gtk.h" 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/infobars/infobar_container_gtk.h" 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/infobars/infobar_gtk.h" 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/location_bar_view_gtk.h" 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/nine_box.h" 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/reload_button_gtk.h" 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/repost_form_warning_gtk.h" 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/status_bubble_gtk.h" 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h" 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/task_manager_gtk.h" 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/theme_install_bubble_view_gtk.h" 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/update_recommended_dialog.h" 7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/omnibox/location_bar.h" 7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/bug_report_ui.h" 7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/window_sizer.h" 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/web_applications/web_app.h" 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h" 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h" 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_widget_host_view.h" 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_view.h" 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/native_web_keyboard_event.h" 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h" 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/app_resources.h" 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h" 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/keycodes/keyboard_codes.h" 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h" 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h" 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/skia_utils_gtk.h" 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The number of milliseconds between loading animation frames. 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kLoadingAnimationFrameTimeMs = 30; 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Default height of dev tools pane when docked to the browser window. This 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// matches the value in Views. 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kDefaultDevToolsHeight = 200; 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst int kMinDevToolsHeight = 50; 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__"; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The frame border is only visible in restored mode and is hardcoded to 4 px 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// on each side regardless of the system window border size. 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kFrameBorderThickness = 4; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// While resize areas on Windows are normally the same size as the window 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// borders, our top area is shrunk by 1 px to make it easier to move the window 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// around with our thinner top grabbable strip. (Incidentally, our side and 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// bottom resize areas don't match the frame border thickness either -- they 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// span the whole nonclient area, so there's no "dead zone" for the mouse.) 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kTopResizeAdjust = 1; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In the window corners, the resize areas don't actually expand bigger, but 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the 16 px at the end of each edge triggers diagonal resizing. 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kResizeAreaCornerSize = 16; 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The thickness of the shadow around the toolbar+web content area. There are 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// actually a couple pixels more that should overlap the toolbar and web 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// content area, but we don't use those pixels. 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kContentShadowThickness = 2; 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The offset to the background when the custom frame is off. We want the 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// window background to line up with the tab background regardless of whether 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// we're in custom frame mode or not. Since themes are designed with the 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// custom frame in mind, we need to offset the background when the custom frame 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is off. 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kCustomFrameBackgroundVerticalOffset = 15; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The timeout in milliseconds before we'll get the true window position with 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// gtk_window_get_position() after the last GTK configure-event signal. 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kDebounceTimeoutMilliseconds = 100; 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Ubuntu patches their verrsion of GTK+ so that there is always a 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// gripper in the bottom right corner of the window. We dynamically 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// look up this symbol because it's a non-standard Ubuntu extension to 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// GTK+. We always need to disable this feature since we can't 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// communicate this to WebKit easily. 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsentypedef void (*gtk_window_set_has_resize_grip_func)(GtkWindow*, gboolean); 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengtk_window_set_has_resize_grip_func gtk_window_set_has_resize_grip_sym; 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid EnsureResizeGripFunction() { 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static bool resize_grip_looked_up = false; 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!resize_grip_looked_up) { 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen resize_grip_looked_up = true; 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_window_set_has_resize_grip_sym = 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen reinterpret_cast<gtk_window_set_has_resize_grip_func>( 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen dlsym(NULL, "gtk_window_set_has_resize_grip")); 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Using gtk_window_get_position/size creates a race condition, so only use 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// this to get the initial bounds. After window creation, we pick up the 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// normal bounds by connecting to the configure-event signal. 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect GetInitialWindowBounds(GtkWindow* window) { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x, y, width, height; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_position(window, &x, &y); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_size(window, &width, &height); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return gfx::Rect(x, y, width, height); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Get the command ids of the key combinations that are not valid gtk 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// accelerators. 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint GetCustomCommandId(GdkEventKey* event) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Filter modifier to only include accelerator modifiers. 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint modifier = event->state & gtk_accelerator_get_default_mod_mask(); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (event->keyval) { 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Gtk doesn't allow GDK_Tab or GDK_ISO_Left_Tab to be an accelerator (see 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_accelerator_valid), so we need to handle these accelerators 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // manually. 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Some X clients (e.g. cygwin, NX client, etc.) also send GDK_KP_Tab when 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // typing a tab key. We should also handle GDK_KP_Tab for such X clients as 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Firefox does. 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Tab: 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_ISO_Left_Tab: 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_KP_Tab: 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GDK_CONTROL_MASK == modifier) { 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IDC_SELECT_NEXT_TAB; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IDC_SELECT_PREVIOUS_TAB; 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return -1; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Get the command ids of the accelerators that we don't want the native widget 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to be able to override. 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint GetPreHandleCommandId(GdkEventKey* event) { 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Filter modifier to only include accelerator modifiers. 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint modifier = event->state & gtk_accelerator_get_default_mod_mask(); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (event->keyval) { 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Page_Down: 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GDK_CONTROL_MASK == modifier) { 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IDC_SELECT_NEXT_TAB; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IDC_MOVE_TAB_NEXT; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_Page_Up: 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GDK_CONTROL_MASK == modifier) { 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IDC_SELECT_PREVIOUS_TAB; 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IDC_MOVE_TAB_PREVIOUS; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return -1; 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGdkCursorType GdkWindowEdgeToGdkCursorType(GdkWindowEdge edge) { 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (edge) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_NORTH_WEST: 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_TOP_LEFT_CORNER; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_NORTH: 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_TOP_SIDE; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_NORTH_EAST: 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_TOP_RIGHT_CORNER; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_WEST: 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_LEFT_SIDE; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_EAST: 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_RIGHT_SIDE; 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_SOUTH_WEST: 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_BOTTOM_LEFT_CORNER; 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_SOUTH: 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_BOTTOM_SIDE; 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GDK_WINDOW_EDGE_SOUTH_EAST: 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_BOTTOM_RIGHT_CORNER; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GDK_LAST_CURSOR; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A helper method for setting the GtkWindow size that should be used in place 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of calling gtk_window_resize directly. This is done to avoid a WM "feature" 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// where setting the window size to the monitor size causes the WM to set the 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// EWMH for full screen mode. 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SetWindowSize(GtkWindow* window, const gfx::Size& size) { 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkScreen* screen = gtk_window_get_screen(window); 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gint num_monitors = gdk_screen_get_n_monitors(screen); 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Make sure the window doesn't match any monitor size. We compare against 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // all monitors because we don't know which monitor the window is going to 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // open on (the WM decides that). 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (gint i = 0; i < num_monitors; ++i) { 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkRectangle monitor_size; 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gdk_screen_get_monitor_geometry(screen, i, &monitor_size); 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (gfx::Size(monitor_size.width, monitor_size.height) == size) { 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_window_resize(window, size.width(), size.height() - 1); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_window_resize(window, size.width(), size.height()); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGQuark GetBrowserWindowQuarkKey() { 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static GQuark quark = g_quark_from_static_string(kBrowserWindowKey); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return quark; 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_; 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserWindowGtk::BrowserWindowGtk(Browser* browser) 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : browser_(browser), 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch state_(GDK_WINDOW_STATE_WITHDRAWN), 277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bookmark_bar_is_floating_(false), 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_cursor_(NULL), 279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()), 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last_click_time_(0), 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch maximize_after_show_(false), 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suppress_window_raise_(false), 283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick accel_group_(NULL), 284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen debounce_timer_disabled_(false), 285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch infobar_arrow_model_(this) { 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBrowserWindowGtk::~BrowserWindowGtk() { 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ui::ActiveWindowWatcherX::RemoveObserver(this); 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser_->tabstrip_model()->RemoveObserver(this); 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::Init() { 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We register first so that other views like the toolbar can use the 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is_active() function in their ActiveWindowChanged() handlers. 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::ActiveWindowWatcherX::AddObserver(this); 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch use_custom_frame_pref_.Init(prefs::kUseCustomChromeFrame, 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->profile()->GetPrefs(), this); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // In some (older) versions of compiz, raising top-level windows when they 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // are partially off-screen causes them to get snapped back on screen, not 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // always even on the current virtual desktop. If we are running under 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // compiz, suppress such raises, as they are not necessary in compiz anyway. 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string wm_name; 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::GetWindowManagerName(&wm_name) && wm_name == "compiz") 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suppress_window_raise_ = true; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_set_qdata(G_OBJECT(window_), GetBrowserWindowQuarkKey(), this); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK | 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GDK_POINTER_MOTION_MASK); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Disable the resize gripper on Ubuntu. 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EnsureResizeGripFunction(); 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (gtk_window_set_has_resize_grip_sym) 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_window_set_has_resize_grip_sym(GTK_WINDOW(window_), FALSE); 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add this window to its own unique window group to allow for 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // window-to-parent modality. 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_group_add_window(gtk_window_group_new(), window_); 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(gtk_window_get_group(window_)); 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (browser_->type() & Browser::TYPE_APP) { 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string app_name = browser_->app_name(); 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (app_name != DevToolsWindow::kDevToolsApp) { 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string wmclassname = web_app::GetWMClassFromAppName(app_name); 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<base::Environment> env(base::Environment::Create()); 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (base::nix::GetDesktopEnvironment(env.get()) == 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::nix::DESKTOP_ENVIRONMENT_XFCE) { 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Workaround for XFCE. XFCE seems to treat the class as a user 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // displayed title, which our app name certainly isn't. They don't have 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // a dock or application based behaviour so do what looks good. 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_window_set_wmclass(window_, 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wmclassname.c_str(), 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gdk_get_program_class()); 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Most everything else uses the wmclass_class to group windows 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // together (docks, per application stuff, etc). Hopefully they won't 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // display wmclassname to the user. 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_window_set_wmclass(window_, 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen g_get_prgname(), 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wmclassname.c_str()); 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_window_set_role(window_, wmclassname.c_str()); 349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For popups, we initialize widgets then set the window geometry, because 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // popups need the widgets inited before they can set the window size 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // properly. For other windows, we set the geometry first to prevent resize 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // flicker. 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser_->type() & Browser::TYPE_POPUP) { 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitWidgets(); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetGeometryHints(); 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetGeometryHints(); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitWidgets(); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConnectAccelerators(); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the initial background color of widgets. 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetBackgroundColor(); 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HideUnsupportedWindowFeatures(); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget, 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event) { 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Draw the default background. 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_cairo_rectangle(cr, &event->area); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_clip(cr); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (UsingCustomPopupFrame()) { 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DrawPopupFrame(cr, widget, event); 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DrawCustomFrame(cr, widget, event); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DrawContentShadow(cr); 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_destroy(cr); 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (UseCustomFrame() && !IsMaximized()) { 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static NineBox custom_frame_border( 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_TOP_LEFT_CORNER, 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_TOP_CENTER, 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_TOP_RIGHT_CORNER, 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_LEFT_SIDE, 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_RIGHT_SIDE, 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_BOTTOM_LEFT_CORNER, 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_BOTTOM_CENTER, 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_WINDOW_BOTTOM_RIGHT_CORNER); 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_frame_border.RenderToWidget(widget); 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; // Allow subwidgets to paint. 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::DrawContentShadow(cairo_t* cr) { 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Draw the shadow above the toolbar. Tabs on the tabstrip will draw over us. 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* theme_provider = GtkThemeService::GetFrom( 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser()->profile()); 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int left_x, top_y; 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_translate_coordinates(toolbar_->widget(), 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(window_), 0, 0, &left_x, 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &top_y); 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int center_width = window_vbox_->allocation.width; 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* top_center = theme_provider->GetSurfaceNamed( 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_TOP_CENTER, GTK_WIDGET(window_)); 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* top_right = theme_provider->GetSurfaceNamed( 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_TOP_RIGHT_CORNER, GTK_WIDGET(window_)); 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* top_left = theme_provider->GetSurfaceNamed( 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_TOP_LEFT_CORNER, GTK_WIDGET(window_)); 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int center_left_x = left_x; 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ShouldDrawContentDropShadow()) { 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't draw over the corners. 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch center_left_x += top_left->Width() - kContentShadowThickness; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch center_width -= (top_left->Width() + top_right->Width()); 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch center_width += 2 * kContentShadowThickness; 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_center->SetSource(cr, center_left_x, top_y - kContentShadowThickness); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, center_left_x, top_y - kContentShadowThickness, 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch center_width, top_center->Height()); 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only draw the rest of the shadow if the user has the custom frame enabled 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and the browser is not maximized. 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ShouldDrawContentDropShadow()) 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The top left corner has a width of 3 pixels. On Windows, the last column 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // of pixels overlap the toolbar. We just crop it off on Linux. The top 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // corners extend to the base of the toolbar (one pixel above the dividing 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // line). 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int right_x = center_left_x + center_width; 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_left->SetSource( 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cr, left_x - kContentShadowThickness, top_y - kContentShadowThickness); 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The toolbar is shorter in location bar only mode so clip the image to the 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // height of the toolbar + the amount of shadow above the toolbar. 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch left_x - kContentShadowThickness, 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_y - kContentShadowThickness, 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_left->Width(), 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_left->Height()); 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Likewise, we crop off the left column of pixels for the top right corner. 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_right->SetSource(cr, right_x, top_y - kContentShadowThickness); 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch right_x, 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_y - kContentShadowThickness, 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_right->Width(), 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch top_right->Height()); 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fill in the sides. As above, we only draw 2 of the 3 columns on Linux. 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int bottom_y; 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_translate_coordinates(window_vbox_, 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_WIDGET(window_), 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, window_vbox_->allocation.height, 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, &bottom_y); 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |side_y| is where to start drawing the side shadows. The top corners draw 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the sides down to the bottom of the toolbar. 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int side_y = top_y - kContentShadowThickness + top_right->Height(); 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |side_height| is how many pixels to draw for the side borders. We do one 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pixel before the bottom of the web contents because that extra pixel is 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // drawn by the bottom corners. 482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int side_height = bottom_y - side_y - 1; 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (side_height > 0) { 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* left = theme_provider->GetSurfaceNamed( 485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_LEFT_SIDE, GTK_WIDGET(window_)); 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch left->SetSource(cr, left_x - kContentShadowThickness, side_y); 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch left_x - kContentShadowThickness, 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch side_y, 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kContentShadowThickness, 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch side_height); 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* right = theme_provider->GetSurfaceNamed( 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_RIGHT_SIDE, GTK_WIDGET(window_)); 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int right_side_x = 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch right_x + top_right->Width() - kContentShadowThickness - 1; 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch right->SetSource(cr, right_side_x, side_y); 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch right_side_x, 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch side_y, 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kContentShadowThickness, 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch side_height); 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Draw the bottom corners. The bottom corners also draw the bottom row of 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pixels of the side shadows. 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* bottom_left = theme_provider->GetSurfaceNamed( 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_BOTTOM_LEFT_CORNER, GTK_WIDGET(window_)); 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_left->SetSource(cr, left_x - kContentShadowThickness, bottom_y - 1); 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_paint(cr); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* bottom_right = theme_provider->GetSurfaceNamed( 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_BOTTOM_RIGHT_CORNER, GTK_WIDGET(window_)); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_right->SetSource(cr, right_x - 1, bottom_y - 1); 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_paint(cr); 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Finally, draw the bottom row. Since we don't overlap the contents, we clip 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the top row of pixels. 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* bottom = theme_provider->GetSurfaceNamed( 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_CONTENT_BOTTOM_CENTER, GTK_WIDGET(window_)); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom->SetSource(cr, left_x + 1, bottom_y - 1); 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch left_x + 1, 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bottom_y, 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_vbox_->allocation.width - 2, 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kContentShadowThickness); 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::DrawPopupFrame(cairo_t* cr, 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* widget, 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event) { 538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* theme_provider = GtkThemeService::GetFrom( 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser()->profile()); 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Like DrawCustomFrame(), except that we use the unthemed resources to draw 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the background. We do this because we can't rely on sane images in the 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // theme that we can draw text on. (We tried using the tab background, but 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that has inverse saturation from what the user usually expects). 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int image_name = GetThemeFrameResource(); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* surface = theme_provider->GetUnthemedSurfaceNamed( 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch image_name, widget); 548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch surface->SetSource(cr, 0, GetVerticalOffset()); 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REFLECT); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, event->area.x, event->area.y, 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event->area.width, event->area.height); 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::DrawCustomFrame(cairo_t* cr, 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* widget, 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event) { 558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* theme_provider = GtkThemeService::GetFrom( 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser()->profile()); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int image_name = GetThemeFrameResource(); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* surface = theme_provider->GetSurfaceNamed( 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch image_name, widget); 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event->area.y < surface->Height()) { 566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch surface->SetSource(cr, 0, GetVerticalOffset()); 5674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The frame background isn't tiled vertically. 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_rectangle(cr, event->area.x, event->area.y, 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event->area.width, surface->Height() - event->area.y); 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_fill(cr); 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (theme_provider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !browser()->profile()->IsOffTheRecord()) { 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CairoCachedSurface* theme_overlay = theme_provider->GetSurfaceNamed( 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IsActive() ? IDR_THEME_FRAME_OVERLAY 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : IDR_THEME_FRAME_OVERLAY_INACTIVE, widget); 580201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch theme_overlay->SetSource(cr, 0, GetVerticalOffset()); 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_paint(cr); 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 585201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochint BrowserWindowGtk::GetVerticalOffset() { 586201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return (IsMaximized() || (!UseCustomFrame())) ? 587201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch -kCustomFrameBackgroundVerticalOffset : 0; 588201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 589201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BrowserWindowGtk::GetThemeFrameResource() { 591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool incognito = browser()->profile()->IsOffTheRecord(); 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int image_name; 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsActive()) { 594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen image_name = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME; 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen image_name = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE : 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_THEME_FRAME_INACTIVE; 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return image_name; 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Show() { 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The Browser associated with this browser window must become the active 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // browser at the time Show() is called. This is the natural behaviour under 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Windows, but gtk_widget_show won't show the widget (and therefore won't 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // call OnFocusIn()) until we return to the runloop. Therefore any calls to 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // BrowserList::GetLastActive() (for example, in bookmark_util), will return 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the previous browser instead if we don't explicitly set it here. 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::SetLastActive(browser()); 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_present(window_); 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (maximize_after_show_) { 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_maximize(window_); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch maximize_after_show_ = false; 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we have sized the window by setting a size request for the render 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // area, then undo it so that the render view can later adjust its own 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // size. 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(contents_container_->widget(), -1, -1); 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::ShowInactive() { 625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_window_set_focus_on_map(window_, false); 626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_widget_show(GTK_WIDGET(window_)); 627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowserWindowGtk::SetBoundsImpl(const gfx::Rect& bounds, 6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool exterior, 6313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool move) { 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x = static_cast<gint>(bounds.x()); 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint y = static_cast<gint>(bounds.y()); 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint width = static_cast<gint>(bounds.width()); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint height = static_cast<gint>(bounds.height()); 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (move) 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_window_move(window_, x, y); 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (exterior) { 6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetWindowSize(window_, gfx::Size(width, height)); 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(contents_container_->widget(), 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch width, height); 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SetBounds(const gfx::Rect& bounds) { 64972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (IsFullscreen()) 65072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetFullscreen(false); 6513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetBoundsImpl(bounds, true, true); 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Close() { 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're already closing. Do nothing. 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!window_) 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!CanClose()) 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We're going to destroy the window, make sure the tab strip isn't running 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // any animations which may still reference GtkWidgets. 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_->StopAnimation(); 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SaveWindowPosition(); 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (accel_group_) { 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Disconnecting the keys we connected to our accelerator group frees the 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // closures allocated in ConnectAccelerators. 67121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AcceleratorsGtk* accelerators = AcceleratorsGtk::GetInstance(); 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (AcceleratorsGtk::const_iterator iter = accelerators->begin(); 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter != accelerators->end(); ++iter) { 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_accel_group_disconnect_key(accel_group_, 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter->second.GetGdkKeyCode(), 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<GdkModifierType>(iter->second.modifiers())); 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_remove_accel_group(window_, accel_group_); 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(accel_group_); 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch accel_group_ = NULL; 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cancel any pending callback from the window configure debounce timer. 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_configure_debounce_timer_.Stop(); 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Likewise for the loading animation. 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loading_animation_timer_.Stop(); 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* window = GTK_WIDGET(window_); 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // To help catch bugs in any event handlers that might get fired during the 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // destruction, set window_ to NULL before any handlers will run. 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_ = NULL; 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch titlebar_->set_window(NULL); 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_destroy(window); 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Activate() { 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_present(window_); 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowserWindowGtk::Deactivate() { 7023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gdk_window_lower(GTK_WIDGET(window_)->window); 7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsActive() const { 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return is_active_; 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::FlashFrame() { 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // May not be respected by all window managers. 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_urgency_hint(window_, TRUE); 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeWindow BrowserWindowGtk::GetNativeHandle() { 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return window_; 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserWindowTesting* BrowserWindowGtk::GetBrowserWindowTesting() { 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochStatusBubble* BrowserWindowGtk::GetStatusBubble() { 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return status_bubble_.get(); 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::ToolbarSizeChanged(bool is_animating) { 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // On Windows, this is used for a performance optimization. 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://code.google.com/p/chromium/issues/detail?id=12291 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateTitleBar() { 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 title = browser_->GetWindowTitleForCurrentTab(); 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_title(window_, UTF16ToUTF8(title).c_str()); 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ShouldShowWindowIcon()) 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch titlebar_->UpdateTitleAndIcon(); 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShelfVisibilityChanged() { 740201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MaybeShowBookmarkBar(false); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateDevTools() { 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateDevToolsForContents( 745201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser_->GetSelectedTabContents()); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateLoadingAnimations(bool should_animate) { 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (should_animate) { 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!loading_animation_timer_.IsRunning()) { 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Loads are happening, and the timer isn't running, so start it. 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loading_animation_timer_.Start( 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this, 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &BrowserWindowGtk::LoadingAnimationCallback); 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (loading_animation_timer_.IsRunning()) { 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loading_animation_timer_.Stop(); 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Loads are now complete, update the state if a task was scheduled. 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LoadingAnimationCallback(); 761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::LoadingAnimationCallback() { 766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser_->type() == Browser::TYPE_NORMAL) { 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Loading animations are shown in the tab for tabbed windows. We check the 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // browser type instead of calling IsTabStripVisible() because the latter 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will return false for fullscreen windows, but we still need to update 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // their animations (so that when they come out of fullscreen mode they'll 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be correct). 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_->UpdateLoadingAnimations(); 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (ShouldShowWindowIcon()) { 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // ... or in the window icon area for popups and app windows. 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* tab_contents = browser_->GetSelectedTabContents(); 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GetSelectedTabContents can return NULL for example under Purify when 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the animations are running slowly and this function is called on 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a timer through LoadingAnimationCallback. 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch titlebar_->UpdateThrobber(tab_contents); 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SetStarredState(bool is_starred) { 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->GetLocationBarView()->SetStarred(is_starred); 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::Rect BrowserWindowGtk::GetRestoredBounds() const { 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return restored_bounds_; 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsengfx::Rect BrowserWindowGtk::GetBounds() const { 79272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return bounds_; 79372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 79472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsMaximized() const { 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (state_ & GDK_WINDOW_STATE_MAXIMIZED); 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::ShouldDrawContentDropShadow() { 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !IsMaximized() && UseCustomFrame(); 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SetFullscreen(bool fullscreen) { 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_window_(un)fullscreen asks the window manager to toggle the EWMH 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // for fullscreen windows. Not all window managers support this. 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (fullscreen) { 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_fullscreen(window_); 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 8093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Work around a bug where if we try to unfullscreen, metacity immediately 8103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // fullscreens us again. This is a little flickery and not necessary if 8113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // there's a gnome-panel, but it's not easy to detect whether there's a 8123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // panel or not. 8133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string wm_name; 8143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool unmaximize_before_unfullscreen = IsMaximized() && 81572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::GetWindowManagerName(&wm_name) && wm_name == "Metacity"; 8163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (unmaximize_before_unfullscreen) 8173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UnMaximize(); 8183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_unfullscreen(window_); 8203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 8213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (unmaximize_before_unfullscreen) 8223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_window_maximize(window_); 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsFullscreen() const { 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (state_ & GDK_WINDOW_STATE_FULLSCREEN); 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsFullscreenBubbleVisible() const { 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return fullscreen_exit_bubble_.get() ? true : false; 832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLocationBar* BrowserWindowGtk::GetLocationBar() const { 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return toolbar_->GetLocationBar(); 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SetFocusToLocationBar(bool select_all) { 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsFullscreen()) 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetLocationBar()->FocusLocation(select_all); 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateReloadStopState(bool is_loading, bool force) { 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->GetReloadButton()->ChangeMode( 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch is_loading ? ReloadButtonGtk::MODE_STOP : ReloadButtonGtk::MODE_RELOAD, 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch force); 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 849201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::UpdateToolbar(TabContentsWrapper* contents, 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool should_restore_state) { 851201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch toolbar_->UpdateTabContents(contents->tab_contents(), should_restore_state); 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::FocusToolbar() { 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::FocusAppMenu() { 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::FocusBookmarksToolbar() { 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::FocusChromeOSStatus() { 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::RotatePaneFocus(bool forwards) { 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsBookmarkBarVisible() const { 875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR) && 876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bookmark_bar_.get() && 877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser_->profile()->GetPrefs()->GetBoolean( 878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kShowBookmarkBar) && 879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen browser_->profile()->GetPrefs()->GetBoolean( 880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs::kEnableBookmarkBar)); 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsBookmarkBarAnimating() const { 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsBookmarkBarSupported() && bookmark_bar_->IsAnimating()) 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool BrowserWindowGtk::IsTabStripEditable() const { 89021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return !tabstrip()->IsDragSessionActive() && 89121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !tabstrip()->IsActiveDropTarget(); 89221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 89321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsToolbarVisible() const { 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return IsToolbarSupported(); 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ConfirmAddSearchProvider(const TemplateURL* template_url, 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) { 900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new EditSearchEngineDialog(window_, template_url, NULL, profile); 901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ToggleBookmarkBar() { 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::ToggleWhenVisible(browser_->profile()); 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 907dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid BrowserWindowGtk::ShowAboutChromeDialog() { 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowAboutDialogForProfile(window_, browser_->profile()); 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowUpdateChromeDialog() { 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateRecommendedDialog::Show(window_); 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowTaskManager() { 91672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TaskManagerGtk::Show(false); 91772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 91872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 91972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid BrowserWindowGtk::ShowBackgroundPages() { 92072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen TaskManagerGtk::Show(true); 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowBookmarkBubble(const GURL& url, 924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool already_bookmarked) { 925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->GetLocationBarView()->ShowStarBubble(url, !already_bookmarked); 926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsDownloadShelfVisible() const { 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return download_shelf_.get() && download_shelf_->IsShowing(); 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDownloadShelf* BrowserWindowGtk::GetDownloadShelf() { 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!download_shelf_.get()) 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch download_shelf_.reset(new DownloadShelfGtk(browser_.get(), 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_area_vbox_)); 936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return download_shelf_.get(); 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowRepostFormWarningDialog(TabContents* tab_contents) { 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new RepostFormWarningGtk(GetNativeHandle(), tab_contents); 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowCollectedCookiesDialog(TabContents* tab_contents) { 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Deletes itself on close. 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new CollectedCookiesGtk(GetNativeHandle(), tab_contents); 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowThemeInstallBubble() { 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ThemeInstallBubbleViewGtk::Show(window_); 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, 953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::NativeWindow parent_window) { 95472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen browser::ShowHtmlDialog(parent_window, browser_->profile(), delegate); 955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UserChangedTheme() { 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetBackgroundColor(); 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_invalidate_rect(GTK_WIDGET(window_)->window, 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch >K_WIDGET(window_)->allocation, TRUE); 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateWindowShape(bounds_.width(), bounds_.height()); 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint BrowserWindowGtk::GetExtraRenderViewHeight() const { 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int sum = infobar_container_->TotalHeightOfAnimatingBars(); 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsBookmarkBarSupported() && bookmark_bar_->IsAnimating()) 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sum += bookmark_bar_->GetHeight(); 968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (download_shelf_.get() && download_shelf_->IsClosing()) 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sum += download_shelf_->GetHeight(); 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return sum; 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::TabContentsFocused(TabContents* tab_contents) { 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTIMPLEMENTED(); 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowPageInfo(Profile* profile, 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url, 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NavigationEntry::SSLStatus& ssl, 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool show_history) { 981731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick browser::ShowPageInfoBubble(window_, profile, url, ssl, show_history); 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowAppMenu() { 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->ShowAppMenu(); 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::PreHandleKeyboardEvent( 989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { 990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventKey* os_event = event.os_event; 991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!os_event || event.type != WebKit::WebInputEvent::RawKeyDown) 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We first find out the browser command associated to the |event|. 996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Then if the command is a reserved one, and should be processed immediately 997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // according to the |event|, the command will be executed immediately. 998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Otherwise we just set |*is_keyboard_shortcut| properly and return false. 999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // First check if it's a custom accelerator. 1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int id = GetCustomCommandId(os_event); 1002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Then check if it's a predefined accelerator bound to the window. 1004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (id == -1) { 1005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This piece of code is based on the fact that calling 1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_window_activate_key() method against |window_| may only trigger a 1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // browser command execution, by matching a global accelerator 1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // defined in above |kAcceleratorMap|. 1009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Here we need to retrieve the command id (if any) associated to the 1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // keyboard event. Instead of looking up the command id in above 1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |kAcceleratorMap| table by ourselves, we block the command execution of 1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the |browser_| object then send the keyboard event to the |window_| by 1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // calling gtk_window_activate_key() method, as if we are activating an 1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // accelerator key. Then we can retrieve the command id from the 1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |browser_| object. 1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Pros of this approach: 1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1. We don't need to care about keyboard layout problem, as 1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_window_activate_key() method handles it for us. 1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Cons: 1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1. The logic is a little complicated. 1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 2. We should be careful not to introduce any accelerators that trigger 1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // customized code instead of browser commands. 1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->SetBlockCommandExecution(true); 1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_activate_key(window_, os_event); 1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't need to care about the WindowOpenDisposition value, 1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // because all commands executed in this path use the default value. 1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch id = browser_->GetLastBlockedCommand(NULL); 1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->SetBlockCommandExecution(false); 1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (id == -1) 1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Executing the command may cause |this| object to be destroyed. 103872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (browser_->IsReservedCommandOrKey(id, event) && !event.match_edit_command) 103921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return browser_->ExecuteCommandIfEnabled(id); 1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The |event| is a keyboard shortcut. 1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(is_keyboard_shortcut != NULL); 1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *is_keyboard_shortcut = true; 1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::HandleKeyboardEvent( 1049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NativeWebKeyboardEvent& event) { 1050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventKey* os_event = event.os_event; 1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!os_event || event.type != WebKit::WebInputEvent::RawKeyDown) 1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Handles a key event in following sequence: 1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1. Our special key accelerators, such as ctrl-tab, etc. 1057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 2. Gtk accelerators. 1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This sequence matches the default key press handler of GtkWindow. 1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It's not necessary to care about the keyboard layout, as 1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_window_activate_key() takes care of it automatically. 1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int id = GetCustomCommandId(os_event); 1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (id != -1) 106421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen browser_->ExecuteCommandIfEnabled(id); 1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_activate_key(window_, os_event); 1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1069201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::ShowCreateWebAppShortcutsDialog( 1070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContentsWrapper* tab_contents) { 1071201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateWebApplicationShortcutsDialogGtk::Show(window_, tab_contents); 1072201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 1073201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1074201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::ShowCreateChromeAppShortcutsDialog( 1075201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Profile* profile, const Extension* app) { 1076201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CreateChromeApplicationShortcutsDialogGtk::Show(window_, app); 1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Cut() { 10804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch gtk_util::DoCut(this); 1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Copy() { 10844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch gtk_util::DoCopy(this); 1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Paste() { 10884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch gtk_util::DoPaste(this); 10894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 10904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 10914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid BrowserWindowGtk::PrepareForInstant() { 1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContentsWrapper* contents = contents_container_->tab(); 1093201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (contents) 1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FadeForInstant(true); 1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::ShowInstant(TabContentsWrapper* preview) { 1098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_container_->SetPreview(preview); 1099201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MaybeShowBookmarkBar(false); 1100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContentsWrapper* contents = contents_container_->tab(); 1102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (contents) 1103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CancelInstantFade(); 11043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::HideInstant(bool instant_is_active) { 1107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_container_->PopPreview(); 1108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MaybeShowBookmarkBar(false); 1109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContentsWrapper* contents = contents_container_->tab(); 1111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (contents) { 1112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (instant_is_active) 1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FadeForInstant(false); 1114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch else 1115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CancelInstantFade(); 1116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 11173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickgfx::Rect BrowserWindowGtk::GetInstantBounds() { 1120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return gtk_util::GetWidgetScreenBounds(contents_container_->widget()); 11213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 11223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() { 1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new DownloadInProgressDialogGtk(browser()); 1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::Observe(NotificationType type, 1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type.value) { 1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED: 1132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MaybeShowBookmarkBar(true); 1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::PREF_CHANGED: { 11363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string* pref_name = Details<std::string>(details).ptr(); 1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (*pref_name == prefs::kUseCustomChromeFrame) { 1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateCustomFrame(); 1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Got pref change notification we didn't register for!"; 1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 1143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Got a notification we didn't register for!"; 1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::TabDetachedAt(TabContentsWrapper* contents, int index) { 1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We use index here rather than comparing |contents| because by this time 1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the model has already removed |contents| from its list, so 1153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // browser_->GetSelectedTabContents() will return NULL or something else. 1154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (index == browser_->tabstrip_model()->active_index()) { 1155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch infobar_container_->ChangeTabContents(NULL); 1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UpdateDevToolsForContents(NULL); 1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_container_->DetachTab(contents); 1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::TabSelectedAt(TabContentsWrapper* old_contents, 1162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContentsWrapper* new_contents, 1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index, 1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool user_gesture) { 1165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (old_contents == new_contents) 1166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (old_contents && !old_contents->tab_contents()->is_being_destroyed()) 1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch old_contents->view()->StoreFocus(); 1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update various elements that are interested in knowing the current 1172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TabContents. 1173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch infobar_container_->ChangeTabContents(new_contents->tab_contents()); 1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_container_->SetTab(new_contents); 1175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch UpdateDevToolsForContents(new_contents->tab_contents()); 1176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new_contents->tab_contents()->DidBecomeSelected(); 1178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(estade): after we manage browser activation, add a check to make sure 1179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we are the active browser before calling RestoreFocus(). 1180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser_->tabstrip_model()->closing_all()) { 1181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_contents->view()->RestoreFocus(); 1182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (new_contents->find_tab_helper()->find_ui_active()) 1183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); 1184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update all the UI bits. 1187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateTitleBar(); 1188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateToolbar(new_contents, true); 1189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MaybeShowBookmarkBar(false); 1190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ActiveWindowChanged(GdkWindow* active_window) { 1193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Do nothing if we're in the process of closing the browser window. 1194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!window_) 1195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_active = (GTK_WIDGET(window_)->window == active_window); 1198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool changed = (is_active != is_active_); 1199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (is_active && changed) { 1201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If there's an app modal dialog (e.g., JS alert), try to redirect 1202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the user's attention to the window owning the dialog. 120321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (AppModalDialogQueue::GetInstance()->HasActiveDialog()) { 120421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AppModalDialogQueue::GetInstance()->ActivateModalDialog(); 1205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch is_active_ = is_active; 1210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (changed) { 1211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetBackgroundColor(); 1212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_invalidate_rect(GTK_WIDGET(window_)->window, 1213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch >K_WIDGET(window_)->allocation, TRUE); 1214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For some reason, the above two calls cause the window shape to be 1215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // lost so reset it. 1216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateWindowShape(bounds_.width(), bounds_.height()); 1217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::FadeForInstant(bool animate) { 1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(contents_container_->tab()); 1222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RenderWidgetHostView* rwhv = 1223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_container_->tab()->tab_contents()->GetRenderWidgetHostView(); 1224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (rwhv) { 1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SkColor whitish = SkColorSetARGB(192, 255, 255, 255); 1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rwhv->SetVisuallyDeemphasized(&whitish, animate); 1227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::CancelInstantFade() { 1231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(contents_container_->tab()); 1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen RenderWidgetHostView* rwhv = 1233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen contents_container_->tab()->tab_contents()->GetRenderWidgetHostView(); 1234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (rwhv) 1235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rwhv->SetVisuallyDeemphasized(NULL, false); 1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid BrowserWindowGtk::MaybeShowBookmarkBar(bool animate) { 1239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsBookmarkBarSupported()) 1240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch TabContents* contents = GetDisplayedTabContents(); 1243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool show_bar = false; 1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (contents) { 1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_->SetProfile(contents->profile()); 1247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_->SetPageNavigator(contents); 1248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch show_bar = true; 1249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (show_bar && contents && !contents->ShouldShowBookmarkBar()) { 1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PrefService* prefs = contents->profile()->GetPrefs(); 1253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen show_bar = prefs->GetBoolean(prefs::kShowBookmarkBar) && 1254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefs->GetBoolean(prefs::kEnableBookmarkBar) && 1255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !IsFullscreen(); 1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (show_bar) { 1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_->Show(animate); 1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (IsFullscreen()) { 1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_->EnterFullscreen(); 1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_->Hide(animate); 1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateDevToolsForContents(TabContents* contents) { 1268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContentsWrapper* old_devtools = devtools_container_->tab(); 1269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TabContentsWrapper* devtools_contents = contents ? 1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DevToolsWindow::GetDevToolsContents(contents) : NULL; 1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (old_devtools == devtools_contents) 1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (old_devtools) 1275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen devtools_container_->DetachTab(old_devtools); 1276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen devtools_container_->SetTab(devtools_contents); 1278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (devtools_contents) { 1279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TabContentsViewGtk::WasShown is not called when tab contents is shown by 1280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // anything other than user selecting a Tab. 1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // See TabContentsViewViews::OnWindowPosChanged for reference on how it 1282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // should be implemented. 1283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen devtools_contents->tab_contents()->ShowContents(); 1284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool should_show = old_devtools == NULL && devtools_contents != NULL; 1287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool should_hide = old_devtools != NULL && devtools_contents == NULL; 1288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (should_show) { 1289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(devtools_container_->widget()); 1290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (should_hide) { 1291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Store split offset when hiding devtools window only. 1292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint divider_offset = gtk_paned_get_position(GTK_PANED(contents_split_)); 129372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen browser_->profile()->GetPrefs()-> 129472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SetInteger(prefs::kDevToolsSplitLocation, divider_offset); 1295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_hide(devtools_container_->widget()); 1296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::DestroyBrowser() { 1300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_.reset(); 1301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsengboolean BrowserWindowGtk::OnConfigure(GtkWidget* widget, 130472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GdkEventConfigure* event) { 130572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen gfx::Rect bounds(event->x, event->y, event->width, event->height); 130672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 130772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // When the window moves, we'll get multiple configure-event signals. We can 130872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // also get events when the bounds haven't changed, but the window's stacking 130972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // has, which we aren't interested in. http://crbug.com/70125 131072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (bounds == bounds_) 131172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return FALSE; 131272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetLocationBar()->location_entry()->ClosePopup(); 1314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TabContents* tab_contents = GetDisplayedTabContents(); 131621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (tab_contents) 131721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen tab_contents->WindowMoveOrResizeStarted(); 131821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bounds_.size() != bounds.size()) 1320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OnSizeChanged(bounds.width(), bounds.height()); 1321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We update |bounds_| but not |restored_bounds_| here. The latter needs 1323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to be updated conditionally when the window is non-maximized and non- 1324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // fullscreen, but whether those state updates have been processed yet is 1325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // window-manager specific. We update |restored_bounds_| in the debounced 1326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // handler below, after the window state has been updated. 1327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bounds_ = bounds; 1328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 132972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The GdkEventConfigure* we get here doesn't have quite the right 1330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // coordinates though (they're relative to the drawable window area, rather 1331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // than any window manager decorations, if enabled), so we need to call 1332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gtk_window_get_position() to get the right values. (Otherwise session 1333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // restore, if enabled, will restore windows to incorrect positions.) That's 1334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a round trip to the X server though, so we set a debounce timer and only 1335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // call it (in OnDebouncedBoundsChanged() below) after we haven't seen a 1336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // reconfigure event in a short while. 1337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't use Reset() because the timer may not yet be running. 1338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (In that case Stop() is a no-op.) 1339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!debounce_timer_disabled_) { 1340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen window_configure_debounce_timer_.Stop(); 1341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen window_configure_debounce_timer_.Start(base::TimeDelta::FromMilliseconds( 1342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kDebounceTimeoutMilliseconds), this, 1343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &BrowserWindowGtk::OnDebouncedBoundsChanged); 1344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 134572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 134672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return FALSE; 1347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::OnDebouncedBoundsChanged() { 1350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint x, y; 1351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_get_position(window_, &x, &y); 1352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point origin(x, y); 1353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bounds_.set_origin(origin); 1354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsFullscreen() && !IsMaximized()) 1355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch restored_bounds_ = bounds_; 1356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SaveWindowPosition(); 1357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 135972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsengboolean BrowserWindowGtk::OnWindowState(GtkWidget* sender, 136072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GdkEventWindowState* event) { 136172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen state_ = event->new_window_state; 1362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) { 136472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen bool is_fullscreen = state_ & GDK_WINDOW_STATE_FULLSCREEN; 1365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->UpdateCommandsForFullscreenMode(is_fullscreen); 1366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (is_fullscreen) { 1367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateCustomFrame(); 1368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->Hide(); 1369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_->Hide(); 1370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsBookmarkBarSupported()) 1371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_->EnterFullscreen(); 1372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_kiosk = 1373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode); 1374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!is_kiosk) { 1375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fullscreen_exit_bubble_.reset(new FullscreenExitBubbleGtk( 1376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_FLOATING_CONTAINER(render_area_floating_container_))); 1377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_hide(toolbar_border_); 1379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch fullscreen_exit_bubble_.reset(); 1381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateCustomFrame(); 1382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ShowSupportedWindowFeatures(); 1383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateWindowShape(bounds_.width(), bounds_.height()); 1387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SaveWindowPosition(); 138872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return FALSE; 138972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 139072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 139172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Callback for the delete event. This event is fired when the user tries to 139272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// close the window (e.g., clicking on the X in the window manager title bar). 139372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsengboolean BrowserWindowGtk::OnMainWindowDeleteEvent(GtkWidget* widget, 139472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GdkEvent* event) { 139572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Close(); 139672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 139772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Return true to prevent the gtk window from being destroyed. Close will 139872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // destroy it for us. 139972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return TRUE; 140072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 140172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 140272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid BrowserWindowGtk::OnMainWindowDestroy(GtkWidget* widget) { 140372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // BUG 8712. When we gtk_widget_destroy() in Close(), this will emit the 140472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // signal right away, and we will be here (while Close() is still in the 140572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // call stack). In order to not reenter Close(), and to also follow the 140672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // expectations of BrowserList, we should run the BrowserWindowGtk destructor 140772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // not now, but after the run loop goes back to process messages. Otherwise 140872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // we will remove ourself from BrowserList while it's being iterated. 140972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Additionally, now that we know the window is gone, we need to make sure to 141072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // set window_ to NULL, otherwise we will try to close the window again when 141172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // we call Close() in the destructor. 141272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 141372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We don't want to use DeleteSoon() here since it won't work on a nested pump 141472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // (like in UI tests). 141572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MessageLoop::current()->PostTask(FROM_HERE, 141672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen new DeleteTask<BrowserWindowGtk>(this)); 1417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UnMaximize() { 1420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_unmaximize(window_); 1421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It can happen that you end up with a window whose restore size is the same 1423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // as the size of the screen, so unmaximizing it merely remaximizes it due to 1424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the same WM feature that SetWindowSize() works around. We try to detect 1425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // this and resize the window to work around the issue. 1426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bounds_.size() == restored_bounds_.size()) 1427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_resize(window_, bounds_.width(), bounds_.height() - 1); 1428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::CanClose() const { 1431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // You cannot close a frame for which there is an active originating drag 1432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // session. 1433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (tabstrip_->IsDragSessionActive()) 1434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Give beforeunload handlers the chance to cancel the close before we hide 1437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the window below. 1438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!browser_->ShouldCloseWindow()) 1439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1441731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!browser_->tabstrip_model()->empty()) { 1442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Tab strip isn't empty. Hide the window (so it appears to have closed 1443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // immediately) and close all the tabs, allowing the renderers to shut 1444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // down. When the tab strip is empty we'll be called back again. 1445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_hide(GTK_WIDGET(window_)); 1446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->OnWindowClosing(); 1447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 1448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Empty TabStripModel, it's now safe to allow the Window to be closed. 1451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 1452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::WINDOW_CLOSED, 1453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<GtkWindow>(window_), 1454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::NoDetails()); 1455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 1456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::ShouldShowWindowIcon() const { 1459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); 1460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid BrowserWindowGtk::DisableDebounceTimerForTests(bool is_disabled) { 1463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen debounce_timer_disabled_ = is_disabled; 1464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_disabled) 1465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen window_configure_debounce_timer_.Stop(); 1466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) { 1469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_floating_container_add_floating( 1470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GTK_FLOATING_CONTAINER(render_area_floating_container_), 1471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch findbar->widget()); 1472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ResetCustomFrameCursor() { 1475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!frame_cursor_) 1476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_cursor_ = NULL; 1479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL); 1480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 1483c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow( 1484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::NativeWindow window) { 1485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (window) { 1486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return static_cast<BrowserWindowGtk*>( 1487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_get_qdata(G_OBJECT(window), GetBrowserWindowQuarkKey())); 1488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 1491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 1494c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWindow* BrowserWindowGtk::GetBrowserWindowForXID(XID xid) { 1495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::map<XID, GtkWindow*>::iterator iter = 1496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserWindowGtk::xid_map_.find(xid); 1497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (iter != BrowserWindowGtk::xid_map_.end()) ? iter->second : NULL; 1498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 1501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::RegisterUserPrefs(PrefService* prefs) { 1502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool custom_frame_default = false; 1503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Avoid checking the window manager if we're not connected to an X server (as 1504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is the case in Valgrind tests). 150572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (ui::XDisplayExists() && 1506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !prefs->HasPrefPath(prefs::kUseCustomChromeFrame)) { 1507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_frame_default = GetCustomFramePrefDefault(); 1508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs->RegisterBooleanPref( 1510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch prefs::kUseCustomChromeFrame, custom_frame_default); 1511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::BookmarkBarIsFloating(bool is_floating) { 1514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bookmark_bar_is_floating_ = is_floating; 1515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->UpdateForBookmarkBarVisibility(is_floating); 1516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This can be NULL during initialization of the bookmark bar. 1518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (bookmark_bar_.get()) 1519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PlaceBookmarkBar(is_floating); 1520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1522201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochTabContents* BrowserWindowGtk::GetDisplayedTabContents() { 1523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return contents_container_->GetVisibleTabContents(); 1524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 1525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::QueueToolbarRedraw() { 1527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_queue_draw(toolbar_->widget()); 1528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SetGeometryHints() { 1531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we call gtk_window_maximize followed by gtk_window_present, compiz gets 1532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // confused and maximizes the window, but doesn't set the 1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GDK_WINDOW_STATE_MAXIMIZED bit. So instead, we keep track of whether to 1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // maximize and call it after gtk_window_present. 1535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch maximize_after_show_ = browser_->GetSavedMaximizedState(); 1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect bounds = browser_->GetSavedWindowBounds(); 1538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't blindly call SetBounds here: that sets a forced position 1539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // on the window and we intentionally *don't* do that for normal 1540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // windows. Most programs do not restore their window position on 1541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Linux, instead letting the window manager choose a position. 1542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // However, in cases like dropping a tab where the bounds are 1544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // specifically set, we do want to position explicitly. We also 1545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // force the position as part of session restore, as applications 1546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that restore other, similar state (for instance GIMP, audacity, 1547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pidgin, dia, and gkrellm) do tend to restore their positions. 1548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 1549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // For popup windows, we assume that if x == y == 0, the opening page 1550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // did not specify a position. Let the WM position the popup instead. 1551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_popup = browser_->type() & Browser::TYPE_POPUP; 15523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool popup_without_position = is_popup && 15533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bounds.x() == 0 && bounds.y() == 0; 15543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool move = browser_->bounds_overridden() && !popup_without_position; 15553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetBoundsImpl(bounds, !is_popup, move); 1556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ConnectHandlersToSignals() { 1559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "delete-event", 156072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen G_CALLBACK(OnMainWindowDeleteEventThunk), this); 1561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "destroy", 156272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen G_CALLBACK(OnMainWindowDestroyThunk), this); 1563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "configure-event", 156472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen G_CALLBACK(OnConfigureThunk), this); 1565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "window-state-event", 156672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen G_CALLBACK(OnWindowStateThunk), this); 1567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "map", 1568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(MainWindowMapped), NULL); 1569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "unmap", 1570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(MainWindowUnMapped), NULL); 1571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "key-press-event", 1572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnKeyPressThunk), this); 1573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "motion-notify-event", 1574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnMouseMoveEventThunk), this); 1575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "button-press-event", 1576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnButtonPressEventThunk), this); 1577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "focus-in-event", 1578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnFocusInThunk), this); 1579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_, "focus-out-event", 1580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch G_CALLBACK(OnFocusOutThunk), this); 1581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::InitWidgets() { 1584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConnectHandlersToSignals(); 1585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bounds_ = restored_bounds_ = GetInitialWindowBounds(window_); 1586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This vbox encompasses all of the widgets within the browser. This is 1588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // everything except the custom frame border. 1589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_vbox_ = gtk_vbox_new(FALSE, 0); 1590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(window_vbox_); 1591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We hold an always hidden GtkMenuBar inside our browser window simply to 1593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // fool the Unity desktop, which will mirror the contents of the first 1594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // GtkMenuBar it sees into the global menu bar. (It doesn't seem to check the 1595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // visibility of the GtkMenuBar, so we can just permanently hide it.) 1596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGlobalGnomeMenu)) { 1597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen global_menu_bar_.reset(new GlobalMenuBar(browser_.get(), this)); 1598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gtk_container_add(GTK_CONTAINER(window_vbox_), global_menu_bar_->widget()); 1599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The window container draws the custom browser frame. 1602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch window_container_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 1603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_name(window_container_, "chrome-custom-frame-border"); 1604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_app_paintable(window_container_, TRUE); 1605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_double_buffered(window_container_, FALSE); 1606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_redraw_on_allocate(window_container_, TRUE); 1607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window_container_, "expose-event", 1608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick G_CALLBACK(OnCustomFrameExposeThunk), this); 1609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(window_container_), window_vbox_); 1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_.reset(new TabStripGtk(browser_->tabstrip_model(), this)); 1612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_->Init(); 1613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Build the titlebar (tabstrip + header space + min/max/close buttons). 1615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch titlebar_.reset(new BrowserTitlebar(this, window_)); 1616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Insert the tabstrip into the window. 1618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(window_vbox_), titlebar_->widget(), FALSE, FALSE, 1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0); 1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_.reset(new BrowserToolbarGtk(browser_.get(), this)); 1622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->Init(browser_->profile(), window_); 1623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(window_vbox_), toolbar_->widget(), 1624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 1625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick g_signal_connect_after(toolbar_->widget(), "expose-event", 1626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick G_CALLBACK(OnExposeDrawInfobarBitsThunk), this); 1627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This vbox surrounds the render area: find bar, info bars and render view. 1628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The reason is that this area as a whole needs to be grouped in its own 1629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GdkWindow hierarchy so that animations originating inside it (infobar, 1630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // download shelf, find bar) are all clipped to that area. This is why 1631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |render_area_vbox_| is packed in |render_area_event_box_|. 1632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_area_vbox_ = gtk_vbox_new(FALSE, 0); 1633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_name(render_area_vbox_, "chrome-render-area-vbox"); 1634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_area_floating_container_ = gtk_floating_container_new(); 1635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(render_area_floating_container_), 1636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_area_vbox_); 1637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen GtkWidget* location_icon = toolbar_->GetLocationBarView()-> 16393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen location_icon_widget(); 16403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen g_signal_connect(location_icon, "size-allocate", 16413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen G_CALLBACK(OnLocationIconSizeAllocateThunk), this); 16423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen g_signal_connect_after(location_icon, "expose-event", 16433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen G_CALLBACK(OnExposeDrawInfobarBitsThunk), this); 16443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_border_ = gtk_event_box_new(); 1646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(render_area_vbox_), 1647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_border_, FALSE, FALSE, 0); 1648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(toolbar_border_, -1, 1); 1649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_no_show_all(toolbar_border_, TRUE); 1650731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick g_signal_connect_after(toolbar_border_, "expose-event", 1651731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick G_CALLBACK(OnExposeDrawInfobarBitsThunk), this); 1652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsToolbarSupported()) 1654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(toolbar_border_); 1655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch infobar_container_.reset(new InfoBarContainerGtk(browser_->profile())); 1657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(render_area_vbox_), 1658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch infobar_container_->widget(), 1659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 1660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_bubble_.reset(new StatusBubbleGtk(browser_->profile())); 1662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch contents_container_.reset(new TabContentsContainerGtk(status_bubble_.get())); 1664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch devtools_container_.reset(new TabContentsContainerGtk(NULL)); 1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ViewIDUtil::SetID(devtools_container_->widget(), VIEW_ID_DEV_TOOLS_DOCKED); 1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch contents_split_ = gtk_vpaned_new(); 1667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_paned_pack1(GTK_PANED(contents_split_), contents_container_->widget(), 1668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TRUE, TRUE); 1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_paned_pack2(GTK_PANED(contents_split_), devtools_container_->widget(), 1670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, TRUE); 1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(render_area_vbox_), contents_split_, TRUE, TRUE, 0); 1672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Restore split offset. 167372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int split_offset = browser_->profile()->GetPrefs()-> 167472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GetInteger(prefs::kDevToolsSplitLocation); 1675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (split_offset != -1) { 1676513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (split_offset < kMinDevToolsHeight) 1677513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch split_offset = kMinDevToolsHeight; 1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_paned_set_position(GTK_PANED(contents_split_), split_offset); 1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(devtools_container_->widget(), -1, 1681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kDefaultDevToolsHeight); 1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(render_area_floating_container_); 1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_hide(devtools_container_->widget()); 1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_area_event_box_ = gtk_event_box_new(); 1686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set a white background so during startup the user sees white in the 1687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // content area before we get a TabContents in place. 1688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(render_area_event_box_, GTK_STATE_NORMAL, 1689513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch >k_util::kGdkWhite); 1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(render_area_event_box_), 1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch render_area_floating_container_); 1692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(render_area_event_box_); 1693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(window_vbox_), render_area_event_box_, 1694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TRUE, TRUE, 0); 1695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsBookmarkBarSupported()) { 1697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_bar_.reset(new BookmarkBarGtk(this, 1698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->profile(), 1699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_.get(), 1700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_.get())); 1701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PlaceBookmarkBar(false); 1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(bookmark_bar_->widget()); 1703731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1704731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick g_signal_connect_after(bookmark_bar_->widget(), "expose-event", 1705731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick G_CALLBACK(OnBookmarkBarExposeThunk), this); 1706731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick g_signal_connect(bookmark_bar_->widget(), "size-allocate", 1707731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick G_CALLBACK(OnBookmarkBarSizeAllocateThunk), this); 1708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We have to realize the window before we try to apply a window shape mask. 1711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_realize(GTK_WIDGET(window_)); 1712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch state_ = gdk_window_get_state(GTK_WIDGET(window_)->window); 1713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that calling this the first time is necessary to get the 1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // proper control layout. 1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateCustomFrame(); 1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1717dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // We have to call this after the first window is created, but after that only 1718dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // when the theme changes. 1719dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static bool default_icon_set = false; 1720dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!default_icon_set) { 1721dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gtk_util::SetDefaultWindowIcon(window_); 1722dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen default_icon_set = true; 1723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1724dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(window_), window_container_); 1726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(window_container_); 1727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->tabstrip_model()->AddObserver(this); 1728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SetBackgroundColor() { 1731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile = browser()->profile(); 1732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* theme_provider = GtkThemeService::GetFrom(profile); 1733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int frame_color_id; 1734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (UsingCustomPopupFrame()) { 1735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen frame_color_id = ThemeService::COLOR_TOOLBAR; 1736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (IsActive()) { 1737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_color_id = browser()->profile()->IsOffTheRecord() 1738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ? ThemeService::COLOR_FRAME_INCOGNITO 1739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : ThemeService::COLOR_FRAME; 1740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_color_id = browser()->profile()->IsOffTheRecord() 1742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ? ThemeService::COLOR_FRAME_INCOGNITO_INACTIVE 1743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : ThemeService::COLOR_FRAME_INACTIVE; 1744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkColor frame_color = theme_provider->GetColor(frame_color_id); 1747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Paint the frame color on the left, right and bottom. 1749513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GdkColor frame_color_gdk = gfx::SkColorToGdkColor(frame_color); 1750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(GTK_WIDGET(window_), GTK_STATE_NORMAL, 1751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &frame_color_gdk); 1752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the color of the dev tools divider. 1754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(contents_split_, GTK_STATE_NORMAL, &frame_color_gdk); 1755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When the cursor is over the divider, GTK+ normally lightens the background 1757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // color by 1.3 (see LIGHTNESS_MULT in gtkstyle.c). Since we're setting the 1758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // color, override the prelight also. 1759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch color_utils::HSL hsl = { -1, 0.5, 0.65 }; 1760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkColor frame_prelight_color = color_utils::HSLShift(frame_color, hsl); 1761513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GdkColor frame_prelight_color_gdk = 1762513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gfx::SkColorToGdkColor(frame_prelight_color); 1763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(contents_split_, GTK_STATE_PRELIGHT, 1764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &frame_prelight_color_gdk); 1765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkColor border_color = theme_provider->GetBorderColor(); 1767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_modify_bg(toolbar_border_, GTK_STATE_NORMAL, &border_color); 1768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::OnSizeChanged(int width, int height) { 1771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateWindowShape(width, height); 1772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateWindowShape(int width, int height) { 1775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (UseCustomFrame() && !IsFullscreen() && !IsMaximized()) { 1776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make the corners rounded. We set a mask that includes most of the 1777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // window except for a few pixels in each corner. 1778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle top_top_rect = { 3, 0, width - 6, 1 }; 1779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle top_mid_rect = { 1, 1, width - 2, 2 }; 1780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle mid_rect = { 0, 3, width, height - 6 }; 1781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The bottom two rects are mirror images of the top two rects. 1782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle bot_mid_rect = top_mid_rect; 1783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bot_mid_rect.y = height - 3; 1784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle bot_bot_rect = top_top_rect; 1785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bot_bot_rect.y = height - 1; 1786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRegion* mask = gdk_region_rectangle(&top_top_rect); 1787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_union_with_rect(mask, &top_mid_rect); 1788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_union_with_rect(mask, &mid_rect); 1789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_union_with_rect(mask, &bot_mid_rect); 1790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_union_with_rect(mask, &bot_bot_rect); 1791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_shape_combine_region(GTK_WIDGET(window_)->window, mask, 0, 0); 1792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_destroy(mask); 1793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 1, 1794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kFrameBorderThickness, kFrameBorderThickness, kFrameBorderThickness); 1795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // XFCE disables the system decorations if there's an xshape set. 1797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (UseCustomFrame()) { 1798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Disable rounded corners. Simply passing in a NULL region doesn't 1799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // seem to work on KWin, so manually set the shape to the whole window. 1800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRectangle rect = { 0, 0, width, height }; 1801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkRegion* mask = gdk_region_rectangle(&rect); 1802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_shape_combine_region(GTK_WIDGET(window_)->window, mask, 0, 0); 1803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_region_destroy(mask); 1804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 1805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_shape_combine_region(GTK_WIDGET(window_)->window, NULL, 0, 0); 1806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0); 1808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ConnectAccelerators() { 1812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch accel_group_ = gtk_accel_group_new(); 1813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_add_accel_group(window_, accel_group_); 1814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen AcceleratorsGtk* accelerators = AcceleratorsGtk::GetInstance(); 1816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (AcceleratorsGtk::const_iterator iter = accelerators->begin(); 1817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter != accelerators->end(); ++iter) { 1818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_accel_group_connect( 1819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch accel_group_, 1820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch iter->second.GetGdkKeyCode(), 1821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<GdkModifierType>(iter->second.modifiers()), 1822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkAccelFlags(0), 1823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_cclosure_new(G_CALLBACK(OnGtkAccelerator), 1824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GINT_TO_POINTER(iter->first), NULL)); 1825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::UpdateCustomFrame() { 1829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_set_decorated(window_, !UseCustomFrame()); 1830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch titlebar_->UpdateCustomFrame(UseCustomFrame() && !IsFullscreen()); 1831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UpdateWindowShape(bounds_.width(), bounds_.height()); 1832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::SaveWindowPosition() { 1835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Browser::SaveWindowPlacement is used for session restore. 1836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (browser_->ShouldSaveWindowPlacement()) 1837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->SaveWindowPlacement(restored_bounds_, IsMaximized()); 1838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We also need to save the placement for startup. 1840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is a web of calls between views and delegates on Windows, but the 1841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // crux of the logic follows. See also cocoa/browser_window_controller.mm. 184272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!browser_->profile()->GetPrefs()) 1843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 1844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string window_name = browser_->GetWindowPlacementKey(); 1846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryPrefUpdate update(browser_->profile()->GetPrefs(), 1847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen window_name.c_str()); 1848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* window_preferences = update.Get(); 1849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Note that we store left/top for consistency with Windows, but that we 1850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // *don't* obey them; we only use them for computing width/height. See 1851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // comments in SetGeometryHints(). 18523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("left", restored_bounds_.x()); 18533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("top", restored_bounds_.y()); 18543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("right", restored_bounds_.right()); 18553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("bottom", restored_bounds_.bottom()); 18563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetBoolean("maximized", IsMaximized()); 1857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_info_provider( 1859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WindowSizer::CreateDefaultMonitorInfoProvider()); 1860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Rect work_area( 1861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch monitor_info_provider->GetMonitorWorkAreaMatching(restored_bounds_)); 18623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("work_area_left", work_area.x()); 18633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("work_area_top", work_area.y()); 18643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("work_area_right", work_area.right()); 18653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick window_preferences->SetInteger("work_area_bottom", work_area.bottom()); 1866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1868513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid BrowserWindowGtk::SetInfoBarShowing(InfoBar* bar, bool animate) { 1869513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch infobar_arrow_model_.ShowArrowFor(bar, animate); 1870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1872513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid BrowserWindowGtk::PaintStateChanged() { 1873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick InvalidateInfoBarBits(); 1874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid BrowserWindowGtk::InvalidateInfoBarBits() { 1877731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gtk_widget_queue_draw(toolbar_border_); 1878731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gtk_widget_queue_draw(toolbar_->widget()); 1879513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (bookmark_bar_.get() && !bookmark_bar_is_floating_) 1880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gtk_widget_queue_draw(bookmark_bar_->widget()); 1881513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 1882513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1883513209b27ff55e2841eac0e4120199c23acce758Ben Murdochint BrowserWindowGtk::GetXPositionOfLocationIcon(GtkWidget* relative_to) { 1884513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GtkWidget* location_icon = toolbar_->GetLocationBarView()-> 1885513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch location_icon_widget(); 1886513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int x = 0; 1887513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_translate_coordinates( 1888513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch location_icon, relative_to, 1889513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (location_icon->allocation.width + 1) / 2, 1890513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 0, &x, NULL); 1891731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1892513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (GTK_WIDGET_NO_WINDOW(relative_to)) 1893513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch x += relative_to->allocation.x; 1894513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1895513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return x; 1896731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1897731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 18983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid BrowserWindowGtk::OnLocationIconSizeAllocate(GtkWidget* sender, 18993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen GtkAllocation* allocation) { 19003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // The position of the arrow may have changed, so we'll have to redraw it. 19013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen InvalidateInfoBarBits(); 19023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 19033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1904731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickgboolean BrowserWindowGtk::OnExposeDrawInfobarBits(GtkWidget* sender, 1905731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GdkEventExpose* expose) { 1906513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!infobar_arrow_model_.NeedToDrawInfoBarArrow()) 1907731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FALSE; 1908731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1909513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int x = GetXPositionOfLocationIcon(sender); 1910731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1911731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gfx::Rect toolbar_border(toolbar_border_->allocation); 1912731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int y = 0; 1913731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick gtk_widget_translate_coordinates(toolbar_border_, sender, 1914731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 0, toolbar_border.bottom(), 1915731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NULL, &y); 1916513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (GTK_WIDGET_NO_WINDOW(sender)) 1917731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick y += sender->allocation.y; 1918731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // x, y is the bottom middle of the arrow. Now we need to create the bounding 1920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // rectangle. 1921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Size arrow_size = GetInfobarArrowSize(); 1922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect bounds( 1923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Point(x - arrow_size.width() / 2.0, y - arrow_size.height()), 1924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen arrow_size); 1925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1926513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Profile* profile = browser()->profile(); 1927513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch infobar_arrow_model_.Paint( 1928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen sender, expose, bounds, 1929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService::GetFrom(profile)->GetBorderColor()); 1930731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FALSE; 1931731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1932731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::Size BrowserWindowGtk::GetInfobarArrowSize() { 1934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kDefaultWidth = 1935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2 * InfoBarArrowModel::kDefaultArrowSize; 1936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kDefaultHeight = InfoBarArrowModel::kDefaultArrowSize; 1937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kMaxWidth = 30; 1938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kMaxHeight = 24; 1939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen double progress = bookmark_bar_.get() && !bookmark_bar_is_floating_ ? 1941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bookmark_bar_->animation()->GetCurrentValue() : 0.0; 1942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t width = kDefaultWidth + (kMaxWidth - kDefaultWidth) * progress; 1943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t height = kDefaultHeight + (kMaxHeight - kDefaultHeight) * progress; 1944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return gfx::Size(width, height); 1946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1948731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickgboolean BrowserWindowGtk::OnBookmarkBarExpose(GtkWidget* sender, 1949731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GdkEventExpose* expose) { 1950513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!infobar_arrow_model_.NeedToDrawInfoBarArrow()) 1951731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FALSE; 1952731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1953513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (bookmark_bar_is_floating_) 1954513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return FALSE; 1955731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1956513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return OnExposeDrawInfobarBits(sender, expose); 1957731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1958731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1959731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid BrowserWindowGtk::OnBookmarkBarSizeAllocate(GtkWidget* sender, 1960731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GtkAllocation* allocation) { 1961731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The size of the bookmark bar affects how the infobar arrow is drawn on 1962731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // the toolbar. 1963513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (infobar_arrow_model_.NeedToDrawInfoBarArrow()) 1964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen InvalidateInfoBarBits(); 1965731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 1966731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 1968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group, 1969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GObject* acceleratable, 1970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint keyval, 1971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkModifierType modifier, 1972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void* user_data) { 1973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int command_id = GPOINTER_TO_INT(user_data); 1974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserWindowGtk* browser_window = 1975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GetBrowserWindowForNativeWindow(GTK_WINDOW(acceleratable)); 1976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(browser_window != NULL); 197721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return browser_window->browser()->ExecuteCommandIfEnabled(command_id); 1978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Let the focused widget have first crack at the key event so we don't 1981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// override their accelerators. 1982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnKeyPress(GtkWidget* widget, GdkEventKey* event) { 1983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If a widget besides the native view is focused, we have to try to handle 1984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the custom accelerators before letting it handle them. 1985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TabContents* current_tab_contents = 1986201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch browser()->GetSelectedTabContents(); 1987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The current tab might not have a render view if it crashed. 1988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!current_tab_contents || !current_tab_contents->GetContentNativeView() || 1989c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !gtk_widget_is_focus(current_tab_contents->GetContentNativeView())) { 1990c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int command_id = GetCustomCommandId(event); 1991c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (command_id == -1) 1992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch command_id = GetPreHandleCommandId(event); 1993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (command_id != -1 && browser_->ExecuteCommandIfEnabled(command_id)) 1995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 1996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Propagate the key event to child widget first, so we don't override their 1998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // accelerators. 1999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gtk_window_propagate_key_event(GTK_WINDOW(widget), event)) { 2000c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!gtk_window_activate_key(GTK_WINDOW(widget), event)) { 2001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_bindings_activate_event(GTK_OBJECT(widget), event); 2002c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2003c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2004c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2005c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool rv = gtk_window_propagate_key_event(GTK_WINDOW(widget), event); 2006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(rv); 2007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2009c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Prevents the default handler from handling this event. 2010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget, 2014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventMotion* event) { 2015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This method is used to update the mouse cursor when over the edge of the 2016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // custom frame. If the custom frame is off or we're over some other widget, 2017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // do nothing. 2018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!UseCustomFrame() || event->window != widget->window) { 2019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Reset the cursor. 2020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (frame_cursor_) { 2021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame_cursor_ = NULL; 2022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_set_cursor(GTK_WIDGET(window_)->window, NULL); 2023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 2025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Update the cursor if we're on the custom frame border. 2028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkWindowEdge edge; 2029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_hit_edge = GetWindowEdge(static_cast<int>(event->x), 2030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(event->y), &edge); 2031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkCursorType new_cursor = GDK_LAST_CURSOR; 2032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_hit_edge) 2033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_cursor = GdkWindowEdgeToGdkCursorType(edge); 2034c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkCursorType last_cursor = GDK_LAST_CURSOR; 2036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (frame_cursor_) 2037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last_cursor = frame_cursor_->type; 2038c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (last_cursor != new_cursor) { 2040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_hit_edge) { 2041201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch frame_cursor_ = gfx::GetCursor(new_cursor); 2042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2043201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch frame_cursor_ = NULL; 2044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2045201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch gdk_window_set_cursor(GTK_WIDGET(window_)->window, frame_cursor_); 2046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 2048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2049c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2050c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnButtonPressEvent(GtkWidget* widget, 2051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventButton* event) { 2052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Handle back/forward. 2053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event->type == GDK_BUTTON_PRESS) { 2054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event->button == 8) { 2055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->GoBack(CURRENT_TAB); 2056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2057c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (event->button == 9) { 2058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->GoForward(CURRENT_TAB); 2059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2060c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Handle left, middle and right clicks. In particular, we care about clicks 2064c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in the custom frame border and clicks in the titlebar. 2065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make the button press coordinate relative to the browser window. 2067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int win_x, win_y; 2068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_get_origin(GTK_WIDGET(window_)->window, &win_x, &win_y); 2069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkWindowEdge edge; 2071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point point(static_cast<int>(event->x_root - win_x), 2072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(event->y_root - win_y)); 2073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_hit_edge = GetWindowEdge(point.x(), point.y(), &edge); 2074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ignore clicks that are in/below the browser toolbar. 2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* toolbar = toolbar_->widget(); 2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!GTK_WIDGET_VISIBLE(toolbar)) { 2078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the toolbar is not showing, use the location of web contents as the 2079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // boundary of where to ignore clicks. 2080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar = render_area_vbox_; 2081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint toolbar_y; 2083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_get_pointer(toolbar, NULL, &toolbar_y); 2084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_hit_titlebar = !IsFullscreen() && (toolbar_y < 0) 2085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch && !has_hit_edge; 2086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (event->button == 1) { 2087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (GDK_BUTTON_PRESS == event->type) { 2088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint32 last_click_time = last_click_time_; 2089c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::Point last_click_position = last_click_position_; 2090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last_click_time_ = event->time; 2091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last_click_position_ = gfx::Point(static_cast<int>(event->x), 2092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(event->y)); 2093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Raise the window after a click on either the titlebar or the border to 2095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // match the behavior of most window managers, unless that behavior has 2096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // been suppressed. 2097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_) 2098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_raise(GTK_WIDGET(window_)->window); 2099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_hit_titlebar) { 2101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We want to start a move when the user single clicks, but not start a 2102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // move when the user double clicks. However, a double click sends the 2103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // following GDK events: GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE, 2104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE. If we 2105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // start a gtk_window_begin_move_drag on the second GDK_BUTTON_PRESS, 2106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the call to gtk_window_maximize fails. To work around this, we 2107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // keep track of the last click and if it's going to be a double click, 2108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we don't call gtk_window_begin_move_drag. 2109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static GtkSettings* settings = gtk_settings_get_default(); 2110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint double_click_time = 250; 2111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gint double_click_distance = 5; 2112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_get(G_OBJECT(settings), 2113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-double-click-time", &double_click_time, 2114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "gtk-double-click-distance", &double_click_distance, 2115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 2116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint32 click_time = event->time - last_click_time; 21183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int click_move_x = abs(event->x - last_click_position.x()); 21193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int click_move_y = abs(event->y - last_click_position.y()); 2120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (click_time > static_cast<guint32>(double_click_time) || 2122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch click_move_x > double_click_distance || 2123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch click_move_y > double_click_distance) { 2124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ignore drag requests if the window is the size of the screen. 2125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We do this to avoid triggering fullscreen mode in metacity 2126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // (without the --no-force-fullscreen flag) and in compiz (with 2127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Legacy Fullscreen Mode enabled). 21283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!BoundsMatchMonitorSize()) { 2129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_begin_move_drag(window_, event->button, 2130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<gint>(event->x_root), 2131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<gint>(event->y_root), 2132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event->time); 2133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (has_hit_edge) { 2137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_begin_resize_drag(window_, edge, event->button, 2138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<gint>(event->x_root), 2139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<gint>(event->y_root), 2140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch event->time); 2141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (GDK_2BUTTON_PRESS == event->type) { 2144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_hit_titlebar) { 2145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Maximize/restore on double click. 2146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsMaximized()) { 2147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnMaximize(); 2148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_window_maximize(window_); 2150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (event->button == 2) { 2155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_hit_titlebar || has_hit_edge) { 2156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_lower(GTK_WIDGET(window_)->window); 2157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (event->button == 3) { 2160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_hit_titlebar) { 216172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen titlebar_->ShowContextMenu(event); 2162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 2163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; // Continue to propagate the event. 2167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 2170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::MainWindowMapped(GtkWidget* widget) { 2171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Map the X Window ID of the window to our window. 217272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen XID xid = ui::GetX11WindowFromGtkWidget(widget); 2173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserWindowGtk::xid_map_.insert( 2174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::pair<XID, GtkWindow*>(xid, GTK_WINDOW(widget))); 2175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 2178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::MainWindowUnMapped(GtkWidget* widget) { 2179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Unmap the X Window ID. 218072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen XID xid = ui::GetX11WindowFromGtkWidget(widget); 2181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserWindowGtk::xid_map_.erase(xid); 2182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnFocusIn(GtkWidget* widget, 2185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventFocus* event) { 2186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BrowserList::SetLastActive(browser_.get()); 2187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 2188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean BrowserWindowGtk::OnFocusOut(GtkWidget* widget, 2191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventFocus* event) { 2192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE; 2193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::ShowSupportedWindowFeatures() { 2196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsTabStripSupported()) 2197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_->Show(); 2198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsToolbarSupported()) { 2200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->Show(); 2201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show(toolbar_border_); 2202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_window_lower(toolbar_border_->window); 2203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsBookmarkBarSupported()) 2206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch MaybeShowBookmarkBar(false); 2207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::HideUnsupportedWindowFeatures() { 2210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsTabStripSupported()) 2211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch tabstrip_->Hide(); 2212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsToolbarSupported()) 2214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch toolbar_->Hide(); 2215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the bookmark bar shelf is unsupported, then we never create it. 2217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsTabStripSupported() const { 2220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); 2221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsToolbarSupported() const { 2224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || 2225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); 2226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::IsBookmarkBarSupported() const { 2229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR); 2230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::UsingCustomPopupFrame() const { 2233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* theme_provider = GtkThemeService::GetFrom( 2234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser()->profile()); 2235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !theme_provider->UseGtkTheme() && 2236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser()->type() & Browser::TYPE_POPUP; 2237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) { 2240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!UseCustomFrame()) 2241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 2242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsMaximized() || IsFullscreen()) 2244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 2245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (x < kFrameBorderThickness) { 2247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Left edge. 2248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (y < kResizeAreaCornerSize - kTopResizeAdjust) { 2249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_NORTH_WEST; 2250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (y < bounds_.height() - kResizeAreaCornerSize) { 2251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_WEST; 2252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_SOUTH_WEST; 2254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 2256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (x < bounds_.width() - kFrameBorderThickness) { 2257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (y < kFrameBorderThickness - kTopResizeAdjust) { 2258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Top edge. 2259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (x < kResizeAreaCornerSize) { 2260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_NORTH_WEST; 2261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (x < bounds_.width() - kResizeAreaCornerSize) { 2262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_NORTH; 2263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_NORTH_EAST; 2265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (y < bounds_.height() - kFrameBorderThickness) { 2267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ignore the middle content area. 2268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 2269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Bottom edge. 2271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (x < kResizeAreaCornerSize) { 2272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_SOUTH_WEST; 2273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (x < bounds_.width() - kResizeAreaCornerSize) { 2274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_SOUTH; 2275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_SOUTH_EAST; 2277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 2280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Right edge. 2282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (y < kResizeAreaCornerSize - kTopResizeAdjust) { 2283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_NORTH_EAST; 2284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (y < bounds_.height() - kResizeAreaCornerSize) { 2285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_EAST; 2286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *edge = GDK_WINDOW_EDGE_SOUTH_EAST; 2288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 2290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 229172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 229372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 2294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::UseCustomFrame() { 2297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We don't use the custom frame for app mode windows or app window popups. 2298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return use_custom_frame_pref_.GetValue() && 2299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->type() != Browser::TYPE_APP && 2300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch browser_->type() != Browser::TYPE_APP_POPUP; 2301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool BrowserWindowGtk::BoundsMatchMonitorSize() { 23043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // A screen can be composed of multiple monitors. 23053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkScreen* screen = gtk_window_get_screen(window_); 23063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gint monitor_num = gdk_screen_get_monitor_at_window(screen, 23073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GTK_WIDGET(window_)->window); 23083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 23093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkRectangle monitor_size; 23103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor_size); 23113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return bounds_.size() == gfx::Size(monitor_size.width, monitor_size.height); 23123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 23133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) { 2315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* parent = gtk_widget_get_parent(bookmark_bar_->widget()); 2316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (parent) 2317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_remove(GTK_CONTAINER(parent), bookmark_bar_->widget()); 2318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!is_floating) { 2320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Place the bookmark bar at the end of |window_vbox_|; this happens after 2321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we have placed the render area at the end of |window_vbox_| so we will 2322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // be above the render area. 2323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(window_vbox_), bookmark_bar_->widget(), 2324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 2325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Place the bookmark bar at the end of the render area; this happens after 2327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // the tab contents container has been placed there so we will be 2328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // above the webpage (in terms of y). 2329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_end(GTK_BOX(render_area_vbox_), bookmark_bar_->widget(), 2330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FALSE, FALSE, 0); 2331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 2335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool BrowserWindowGtk::GetCustomFramePrefDefault() { 2336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string wm_name; 233772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ui::GetWindowManagerName(&wm_name)) 2338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 2339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ideally, we'd use the custom frame by default and just fall back on using 2341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // system decorations for the few (?) tiling window managers where the custom 2342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // frame doesn't make sense (e.g. awesome, ion3, ratpoison, xmonad, etc.) or 2343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // other WMs where it has issues (e.g. Fluxbox -- see issue 19130). The EWMH 2344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // _NET_SUPPORTING_WM property makes it easy to look up a name for the current 2345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // WM, but at least some of the WMs in the latter group don't set it. 2346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Instead, we default to using system decorations for all WMs and 2347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // special-case the ones where the custom frame should be used. These names 2348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // are taken from the WMs' source code. 2349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return (wm_name == "Blackbox" || 2350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wm_name == "compiz" || 2351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wm_name == "e16" || // Enlightenment DR16 2352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wm_name == "Metacity" || 2353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wm_name == "Mutter" || 2354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wm_name == "Openbox" || 2355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wm_name == "Xfwm4"); 2356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 2357