This source file includes following definitions.
- GetInitialWindowBounds
- GetCustomCommandId
- GetPreHandleCommandId
- GetBrowserWindowQuarkKey
- is_fullscreen_
- Init
- OnCustomFrameExpose
- DrawCustomFrameBorder
- DrawContentShadow
- DrawPopupFrame
- DrawCustomFrame
- GetVerticalOffset
- GetThemeFrameResource
- Show
- ShowInactive
- Hide
- SetBoundsImpl
- SetBounds
- Close
- Activate
- Deactivate
- IsActive
- FlashFrame
- IsAlwaysOnTop
- SetAlwaysOnTop
- GetNativeWindow
- GetBrowserWindowTesting
- GetStatusBubble
- UpdateTitleBar
- BookmarkBarStateChanged
- UpdateDevTools
- UpdateLoadingAnimations
- LoadingAnimationCallback
- SetStarredState
- SetTranslateIconToggled
- OnActiveTabChanged
- ZoomChangedForActiveTab
- GetRestoredBounds
- GetRestoredState
- GetBounds
- IsMaximized
- IsMinimized
- Maximize
- Minimize
- Restore
- ShouldDrawContentDropShadow
- EnterFullscreen
- UpdateFullscreenExitBubbleContent
- ExitFullscreen
- ShouldHideUIForFullscreen
- IsFullscreen
- IsFullscreenBubbleVisible
- GetLocationBar
- SetFocusToLocationBar
- UpdateReloadStopState
- UpdateToolbar
- FocusToolbar
- FocusAppMenu
- FocusBookmarksToolbar
- FocusInfobars
- RotatePaneFocus
- IsBookmarkBarVisible
- IsBookmarkBarAnimating
- IsTabStripEditable
- IsToolbarVisible
- GetRootWindowResizerRect
- ConfirmAddSearchProvider
- ShowUpdateChromeDialog
- ShowBookmarkBubble
- ShowBookmarkAppBubble
- ShowTranslateBubble
- ShowOneClickSigninBubble
- IsDownloadShelfVisible
- GetDownloadShelf
- UserChangedTheme
- GetExtraRenderViewHeight
- WebContentsFocused
- ShowWebsiteSettings
- ShowAppMenu
- PreHandleKeyboardEvent
- HandleKeyboardEvent
- Cut
- Copy
- Paste
- GetDispositionForPopupBounds
- CreateFindBar
- GetWebContentsModalDialogHost
- ShowAvatarBubble
- ShowAvatarBubbleFromAvatarButton
- ShowPasswordGenerationBubble
- ConfirmBrowserCloseWithPendingDownloads
- GetRenderViewHeightInsetWithDetachedBookmarkBar
- ExecuteExtensionCommand
- ShowPageActionPopup
- ShowBrowserActionPopup
- Observe
- TabDetachedAt
- ActiveWindowChanged
- GetInfoBarSeparatorColor
- InfoBarContainerStateChanged
- DrawInfoBarArrows
- GetActiveTabPermissionGranter
- DestroyBrowser
- OnConfigure
- OnDebouncedBoundsChanged
- OnWindowState
- OnMainWindowDeleteEvent
- OnMainWindowDestroy
- UnMaximize
- CanClose
- ShouldShowWindowIcon
- AddFindBar
- ResetCustomFrameCursor
- GetBrowserWindowForNativeWindow
- GetBrowserWindowForXID
- titlebar_widget
- RegisterProfilePrefs
- GetDisplayedTab
- QueueToolbarRedraw
- SetGeometryHints
- ConnectHandlersToSignals
- InitWidgets
- SetBackgroundColor
- UpdateWindowShape
- GetWindowShape
- ConnectAccelerators
- UpdateCustomFrame
- InvalidateWindow
- SaveWindowPosition
- InvalidateInfoBarBits
- GetXPositionOfLocationIcon
- MaybeShowBookmarkBar
- OnLocationIconSizeAllocate
- OnExposeDrawInfobarBits
- OnBookmarkBarExpose
- OnBookmarkBarSizeAllocate
- OnGtkAccelerator
- OnKeyPress
- OnMouseMoveEvent
- OnButtonPressEvent
- OnFocusIn
- OnFocusOut
- ShowSupportedWindowFeatures
- HideUnsupportedWindowFeatures
- IsTabStripSupported
- IsToolbarSupported
- IsBookmarkBarSupported
- UsingCustomPopupFrame
- GetWindowEdge
- UseCustomFrame
- PlaceBookmarkBar
- DrawFrameAsActive
- UpdateDevToolsForContents
- ShowDevToolsContainer
- HideDevToolsContainer
- OnDevToolsContainerSetFloatingPosition
- OnUseCustomChromeFrameChanged
- CreateBrowserWindow
- AdjustHostDesktopType
#include "chrome/browser/ui/gtk/browser_window_gtk.h"
#include <gdk/gdkkeysyms.h>
#include <algorithm>
#include <string>
#include "base/base_paths.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/debug/trace_event.h"
#include "base/environment.h"
#include "base/i18n/file_util_icu.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/message_loop/message_loop.h"
#include "base/nix/xdg_util.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window_state.h"
#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/ui/find_bar/find_tab_helper.h"
#include "chrome/browser/ui/gtk/accelerators_gtk.h"
#include "chrome/browser/ui/gtk/avatar_menu_bubble_gtk.h"
#include "chrome/browser/ui/gtk/avatar_menu_button_gtk.h"
#include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h"
#include "chrome/browser/ui/gtk/browser_titlebar.h"
#include "chrome/browser/ui/gtk/browser_toolbar_gtk.h"
#include "chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h"
#include "chrome/browser/ui/gtk/download/download_in_progress_dialog_gtk.h"
#include "chrome/browser/ui/gtk/download/download_shelf_gtk.h"
#include "chrome/browser/ui/gtk/edit_search_engine_dialog.h"
#include "chrome/browser/ui/gtk/extensions/extension_keybinding_registry_gtk.h"
#include "chrome/browser/ui/gtk/find_bar_gtk.h"
#include "chrome/browser/ui/gtk/fullscreen_exit_bubble_gtk.h"
#include "chrome/browser/ui/gtk/global_menu_bar.h"
#include "chrome/browser/ui/gtk/gtk_theme_service.h"
#include "chrome/browser/ui/gtk/gtk_util.h"
#include "chrome/browser/ui/gtk/gtk_window_util.h"
#include "chrome/browser/ui/gtk/infobars/infobar_container_gtk.h"
#include "chrome/browser/ui/gtk/infobars/infobar_gtk.h"
#include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
#include "chrome/browser/ui/gtk/nine_box.h"
#include "chrome/browser/ui/gtk/one_click_signin_bubble_gtk.h"
#include "chrome/browser/ui/gtk/password_generation_bubble_gtk.h"
#include "chrome/browser/ui/gtk/reload_button_gtk.h"
#include "chrome/browser/ui/gtk/status_bubble_gtk.h"
#include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h"
#include "chrome/browser/ui/gtk/task_manager_gtk.h"
#include "chrome/browser/ui/gtk/update_recommended_dialog.h"
#include "chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#include "ui/base/accelerators/platform_accelerator_gtk.h"
#include "ui/base/gtk/gtk_floating_container.h"
#include "ui/base/gtk/gtk_hig_constants.h"
#include "ui/base/gtk/gtk_screen_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/x/active_window_watcher_x.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/gtk_util.h"
#include "ui/gfx/image/cairo_cached_surface.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/skia_utils_gtk.h"
using content::NativeWebKeyboardEvent;
using content::SSLStatus;
using content::WebContents;
using web_modal::WebContentsModalDialogHost;
namespace {
const int kLoadingAnimationFrameTimeMs = 30;
const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__";
const int kTopResizeAdjust = 1;
const int kContentShadowThickness = 2;
const int kCustomFrameBackgroundVerticalOffset = 15;
const int kDebounceTimeoutMilliseconds = 100;
gfx::Rect GetInitialWindowBounds(GtkWindow* window) {
gint x, y, width, height;
gtk_window_get_position(window, &x, &y);
gtk_window_get_size(window, &width, &height);
return gfx::Rect(x, y, width, height);
}
int GetCustomCommandId(GdkEventKey* event) {
guint modifier = event->state & gtk_accelerator_get_default_mod_mask();
switch (event->keyval) {
case GDK_Tab:
case GDK_ISO_Left_Tab:
case GDK_KP_Tab:
if (GDK_CONTROL_MASK == modifier) {
return IDC_SELECT_NEXT_TAB;
} else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) {
return IDC_SELECT_PREVIOUS_TAB;
}
break;
default:
break;
}
return -1;
}
int GetPreHandleCommandId(GdkEventKey* event) {
guint modifier = event->state & gtk_accelerator_get_default_mod_mask();
switch (event->keyval) {
case GDK_Page_Down:
if (GDK_CONTROL_MASK == modifier) {
return IDC_SELECT_NEXT_TAB;
} else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) {
return IDC_MOVE_TAB_NEXT;
}
break;
case GDK_Page_Up:
if (GDK_CONTROL_MASK == modifier) {
return IDC_SELECT_PREVIOUS_TAB;
} else if ((GDK_CONTROL_MASK | GDK_SHIFT_MASK) == modifier) {
return IDC_MOVE_TAB_PREVIOUS;
}
break;
default:
break;
}
return -1;
}
GQuark GetBrowserWindowQuarkKey() {
static GQuark quark = g_quark_from_static_string(kBrowserWindowKey);
return quark;
}
}
BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
: window_(NULL),
window_has_shown_(false),
window_container_(NULL),
window_vbox_(NULL),
render_area_vbox_(NULL),
render_area_floating_container_(NULL),
render_area_event_box_(NULL),
toolbar_border_(NULL),
browser_(browser),
state_(GDK_WINDOW_STATE_WITHDRAWN),
devtools_window_(NULL),
devtools_floating_container_(NULL),
frame_cursor_(NULL),
is_active_(false),
show_state_after_show_(ui::SHOW_STATE_DEFAULT),
suppress_window_raise_(false),
accel_group_(NULL),
is_fullscreen_(false) {
}
BrowserWindowGtk::~BrowserWindowGtk() {
ui::ActiveWindowWatcherX::RemoveObserver(this);
browser_->tab_strip_model()->RemoveObserver(this);
}
void BrowserWindowGtk::Init() {
ui::ActiveWindowWatcherX::AddObserver(this);
use_custom_frame_pref_.Init(
prefs::kUseCustomChromeFrame,
browser_->profile()->GetPrefs(),
base::Bind(&BrowserWindowGtk::OnUseCustomChromeFrameChanged,
base::Unretained(this)));
if (!browser_->profile()->IsOffTheRecord()) {
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED,
content::NotificationService::AllSources());
}
if (ui::GuessWindowManager() == ui::WM_COMPIZ)
suppress_window_raise_ = true;
window_ = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
g_object_set_qdata(G_OBJECT(window_), GetBrowserWindowQuarkKey(), this);
gtk_widget_add_events(GTK_WIDGET(window_), GDK_BUTTON_PRESS_MASK |
GDK_POINTER_MOTION_MASK);
gtk_window_util::DisableResizeGrip(window_);
gtk_window_group_add_window(gtk_window_group_new(), window_);
g_object_unref(gtk_window_get_group(window_));
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (browser_->is_app()) {
std::string app_name = browser_->app_name();
if (app_name != DevToolsWindow::kDevToolsApp) {
gtk_window_util::SetWindowCustomClass(window_,
web_app::GetWMClassFromAppName(app_name));
}
} else if (command_line.HasSwitch(switches::kUserDataDir)) {
const std::string user_data_dir =
command_line.GetSwitchValueNative(switches::kUserDataDir);
gtk_window_util::SetWindowCustomClass(window_,
std::string(gdk_get_program_class()) + " (" + user_data_dir + ")");
}
if (browser_->is_type_popup()) {
gtk_window_set_role(window_, "pop-up");
InitWidgets();
SetGeometryHints();
} else {
gtk_window_set_role(window_, "browser");
SetGeometryHints();
InitWidgets();
}
ConnectAccelerators();
SetBackgroundColor();
HideUnsupportedWindowFeatures();
if (UseCustomFrame()) {
ui::SetHideTitlebarWhenMaximizedProperty(
ui::GetX11WindowFromGtkWidget(GTK_WIDGET(window_)),
ui::HIDE_TITLEBAR_WHEN_MAXIMIZED);
}
}
gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget,
GdkEventExpose* event) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::OnCustomFrameExpose");
cairo_t* cr = gdk_cairo_create(gtk_widget_get_window(widget));
gdk_cairo_rectangle(cr, &event->area);
cairo_clip(cr);
if (UsingCustomPopupFrame()) {
DrawPopupFrame(cr, widget, event);
} else {
DrawCustomFrame(cr, widget, event);
}
DrawContentShadow(cr);
cairo_destroy(cr);
if (UseCustomFrame() && !IsMaximized())
DrawCustomFrameBorder(widget);
return FALSE;
}
void BrowserWindowGtk::DrawCustomFrameBorder(GtkWidget* widget) {
static NineBox* custom_frame_border = NULL;
if (!custom_frame_border) {
custom_frame_border = new NineBox(IDR_WINDOW_TOP_LEFT_CORNER,
IDR_WINDOW_TOP_CENTER,
IDR_WINDOW_TOP_RIGHT_CORNER,
IDR_WINDOW_LEFT_SIDE,
0,
IDR_WINDOW_RIGHT_SIDE,
IDR_WINDOW_BOTTOM_LEFT_CORNER,
IDR_WINDOW_BOTTOM_CENTER,
IDR_WINDOW_BOTTOM_RIGHT_CORNER);
}
custom_frame_border->RenderToWidget(widget);
}
void BrowserWindowGtk::DrawContentShadow(cairo_t* cr) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
int left_x, top_y;
gtk_widget_translate_coordinates(toolbar_->widget(),
GTK_WIDGET(window_), 0, 0, &left_x,
&top_y);
GtkAllocation window_vbox_allocation;
gtk_widget_get_allocation(window_vbox_, &window_vbox_allocation);
int center_width = window_vbox_allocation.width;
gfx::CairoCachedSurface* top_center =
rb.GetNativeImageNamed(IDR_CONTENT_TOP_CENTER).ToCairo();
gfx::CairoCachedSurface* top_right =
rb.GetNativeImageNamed(IDR_CONTENT_TOP_RIGHT_CORNER).ToCairo();
gfx::CairoCachedSurface* top_left =
rb.GetNativeImageNamed(IDR_CONTENT_TOP_LEFT_CORNER).ToCairo();
int center_left_x = left_x;
if (ShouldDrawContentDropShadow()) {
center_left_x += top_left->Width() - kContentShadowThickness;
center_width -= (top_left->Width() + top_right->Width());
center_width += 2 * kContentShadowThickness;
}
top_center->SetSource(cr, GTK_WIDGET(window_),
center_left_x, top_y - kContentShadowThickness);
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
cairo_rectangle(cr, center_left_x, top_y - kContentShadowThickness,
center_width, top_center->Height());
cairo_fill(cr);
if (!ShouldDrawContentDropShadow())
return;
int right_x = center_left_x + center_width;
top_left->SetSource(cr, GTK_WIDGET(window_),
left_x - kContentShadowThickness, top_y - kContentShadowThickness);
cairo_rectangle(cr,
left_x - kContentShadowThickness,
top_y - kContentShadowThickness,
top_left->Width(),
top_left->Height());
cairo_fill(cr);
top_right->SetSource(cr, GTK_WIDGET(window_),
right_x, top_y - kContentShadowThickness);
cairo_rectangle(cr,
right_x,
top_y - kContentShadowThickness,
top_right->Width(),
top_right->Height());
cairo_fill(cr);
int bottom_y;
gtk_widget_translate_coordinates(window_vbox_,
GTK_WIDGET(window_),
0, window_vbox_allocation.height,
NULL, &bottom_y);
int side_y = top_y - kContentShadowThickness + top_right->Height();
int side_height = bottom_y - side_y - 1;
if (side_height > 0) {
gfx::CairoCachedSurface* left =
rb.GetNativeImageNamed(IDR_CONTENT_LEFT_SIDE).ToCairo();
left->SetSource(cr, GTK_WIDGET(window_),
left_x - kContentShadowThickness, side_y);
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
cairo_rectangle(cr,
left_x - kContentShadowThickness,
side_y,
kContentShadowThickness,
side_height);
cairo_fill(cr);
gfx::CairoCachedSurface* right =
rb.GetNativeImageNamed(IDR_CONTENT_RIGHT_SIDE).ToCairo();
int right_side_x =
right_x + top_right->Width() - kContentShadowThickness - 1;
right->SetSource(cr, GTK_WIDGET(window_), right_side_x, side_y);
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
cairo_rectangle(cr,
right_side_x,
side_y,
kContentShadowThickness,
side_height);
cairo_fill(cr);
}
gfx::CairoCachedSurface* bottom_left =
rb.GetNativeImageNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER).ToCairo();
bottom_left->SetSource(cr, GTK_WIDGET(window_),
left_x - kContentShadowThickness, bottom_y - 1);
cairo_paint(cr);
gfx::CairoCachedSurface* bottom_right =
rb.GetNativeImageNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER).ToCairo();
bottom_right->SetSource(cr, GTK_WIDGET(window_), right_x - 1, bottom_y - 1);
cairo_paint(cr);
gfx::CairoCachedSurface* bottom =
rb.GetNativeImageNamed(IDR_CONTENT_BOTTOM_CENTER).ToCairo();
bottom->SetSource(cr, GTK_WIDGET(window_), left_x + 1, bottom_y - 1);
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
cairo_rectangle(cr,
left_x + 1,
bottom_y,
window_vbox_allocation.width - 2,
kContentShadowThickness);
cairo_fill(cr);
}
void BrowserWindowGtk::DrawPopupFrame(cairo_t* cr,
GtkWidget* widget,
GdkEventExpose* event) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
int image_name = GetThemeFrameResource();
gfx::CairoCachedSurface* surface =
rb.GetNativeImageNamed(image_name).ToCairo();
surface->SetSource(cr, widget, 0, GetVerticalOffset());
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REFLECT);
cairo_rectangle(cr, event->area.x, event->area.y,
event->area.width, event->area.height);
cairo_fill(cr);
}
void BrowserWindowGtk::DrawCustomFrame(cairo_t* cr,
GtkWidget* widget,
GdkEventExpose* event) {
GtkThemeService* theme_provider = GtkThemeService::GetFrom(
browser()->profile());
int image_name = GetThemeFrameResource();
gfx::CairoCachedSurface* surface = theme_provider->GetImageNamed(
image_name).ToCairo();
if (event->area.y < surface->Height()) {
surface->SetSource(cr, widget, 0, GetVerticalOffset());
cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
cairo_rectangle(cr, event->area.x, event->area.y,
event->area.width, surface->Height() - event->area.y);
cairo_fill(cr);
}
if (theme_provider->HasCustomImage(IDR_THEME_FRAME_OVERLAY) &&
!browser()->profile()->IsOffTheRecord()) {
gfx::CairoCachedSurface* theme_overlay = theme_provider->GetImageNamed(
DrawFrameAsActive() ? IDR_THEME_FRAME_OVERLAY
: IDR_THEME_FRAME_OVERLAY_INACTIVE).ToCairo();
theme_overlay->SetSource(cr, widget, 0, GetVerticalOffset());
cairo_paint(cr);
}
}
int BrowserWindowGtk::GetVerticalOffset() {
return (IsMaximized() || (!UseCustomFrame())) ?
-kCustomFrameBackgroundVerticalOffset : 0;
}
int BrowserWindowGtk::GetThemeFrameResource() {
bool incognito = browser()->profile()->IsOffTheRecord();
int image_name;
if (DrawFrameAsActive()) {
image_name = incognito ? IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
} else {
image_name = incognito ? IDR_THEME_FRAME_INCOGNITO_INACTIVE :
IDR_THEME_FRAME_INACTIVE;
}
return image_name;
}
void BrowserWindowGtk::Show() {
BrowserList::SetLastActive(browser());
gtk_window_present(window_);
if (show_state_after_show_ == ui::SHOW_STATE_MAXIMIZED) {
gtk_window_maximize(window_);
show_state_after_show_ = ui::SHOW_STATE_NORMAL;
} else if (show_state_after_show_ == ui::SHOW_STATE_MINIMIZED) {
gtk_window_iconify(window_);
show_state_after_show_ = ui::SHOW_STATE_NORMAL;
}
gtk_widget_set_size_request(devtools_floating_container_, -1, -1);
window_has_shown_ = true;
browser()->OnWindowDidShow();
}
void BrowserWindowGtk::ShowInactive() {
gtk_window_set_focus_on_map(window_, false);
gtk_widget_show(GTK_WIDGET(window_));
}
void BrowserWindowGtk::Hide() {
}
void BrowserWindowGtk::SetBoundsImpl(const gfx::Rect& bounds,
bool exterior,
bool move) {
gint x = static_cast<gint>(bounds.x());
gint y = static_cast<gint>(bounds.y());
gint width = static_cast<gint>(bounds.width());
gint height = static_cast<gint>(bounds.height());
if (move)
gtk_window_move(window_, x, y);
if (exterior) {
gtk_window_util::SetWindowSize(window_, gfx::Size(width, height));
} else {
gtk_widget_set_size_request(devtools_floating_container_,
width, height);
}
}
void BrowserWindowGtk::SetBounds(const gfx::Rect& bounds) {
if (IsFullscreen())
ExitFullscreen();
SetBoundsImpl(bounds, true, true);
}
void BrowserWindowGtk::Close() {
if (!window_)
return;
if (!CanClose())
return;
tabstrip_->StopAnimation();
SaveWindowPosition();
if (accel_group_) {
AcceleratorsGtk* accelerators = AcceleratorsGtk::GetInstance();
for (AcceleratorsGtk::const_iterator iter = accelerators->begin();
iter != accelerators->end(); ++iter) {
gtk_accel_group_disconnect_key(accel_group_,
ui::GetGdkKeyCodeForAccelerator(iter->second),
ui::GetGdkModifierForAccelerator(iter->second));
}
gtk_window_remove_accel_group(window_, accel_group_);
g_object_unref(accel_group_);
accel_group_ = NULL;
}
window_configure_debounce_timer_.Stop();
loading_animation_timer_.Stop();
GtkWidget* window = GTK_WIDGET(window_);
window_ = NULL;
window_container_ = NULL;
window_vbox_ = NULL;
render_area_vbox_ = NULL;
render_area_floating_container_ = NULL;
render_area_event_box_ = NULL;
toolbar_border_ = NULL;
devtools_floating_container_ = NULL;
window_has_shown_ = false;
titlebar_->set_window(NULL);
global_menu_bar_->Disable();
gtk_widget_destroy(window);
}
void BrowserWindowGtk::Activate() {
gtk_window_present(window_);
}
void BrowserWindowGtk::Deactivate() {
gdk_window_lower(gtk_widget_get_window(GTK_WIDGET(window_)));
}
bool BrowserWindowGtk::IsActive() const {
if (ui::ActiveWindowWatcherX::WMSupportsActivation())
return is_active_;
return window_ && gtk_window_is_active(window_);
}
void BrowserWindowGtk::FlashFrame(bool flash) {
gtk_window_set_urgency_hint(window_, flash);
}
bool BrowserWindowGtk::IsAlwaysOnTop() const {
return false;
}
void BrowserWindowGtk::SetAlwaysOnTop(bool always_on_top) {
NOTIMPLEMENTED();
}
gfx::NativeWindow BrowserWindowGtk::GetNativeWindow() {
return window_;
}
BrowserWindowTesting* BrowserWindowGtk::GetBrowserWindowTesting() {
NOTIMPLEMENTED();
return NULL;
}
StatusBubble* BrowserWindowGtk::GetStatusBubble() {
return status_bubble_.get();
}
void BrowserWindowGtk::UpdateTitleBar() {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::UpdateTitleBar");
base::string16 title = browser_->GetWindowTitleForCurrentTab();
gtk_window_set_title(window_, base::UTF16ToUTF8(title).c_str());
if (ShouldShowWindowIcon())
titlebar_->UpdateTitleAndIcon();
}
void BrowserWindowGtk::BookmarkBarStateChanged(
BookmarkBar::AnimateChangeType change_type) {
MaybeShowBookmarkBar(change_type == BookmarkBar::ANIMATE_STATE_CHANGE);
}
void BrowserWindowGtk::UpdateDevTools() {
UpdateDevToolsForContents(
browser_->tab_strip_model()->GetActiveWebContents());
}
void BrowserWindowGtk::UpdateLoadingAnimations(bool should_animate) {
if (should_animate) {
if (!loading_animation_timer_.IsRunning()) {
loading_animation_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this,
&BrowserWindowGtk::LoadingAnimationCallback);
}
} else {
if (loading_animation_timer_.IsRunning()) {
loading_animation_timer_.Stop();
LoadingAnimationCallback();
}
}
}
void BrowserWindowGtk::LoadingAnimationCallback() {
if (browser_->is_type_tabbed()) {
tabstrip_->UpdateLoadingAnimations();
} else if (ShouldShowWindowIcon()) {
WebContents* web_contents =
browser_->tab_strip_model()->GetActiveWebContents();
titlebar_->UpdateThrobber(web_contents);
}
}
void BrowserWindowGtk::SetStarredState(bool is_starred) {
toolbar_->GetLocationBarView()->SetStarred(is_starred);
}
void BrowserWindowGtk::SetTranslateIconToggled(bool is_lit) {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::OnActiveTabChanged(WebContents* old_contents,
WebContents* new_contents,
int index,
int reason) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::ActiveTabChanged");
if (old_contents && !old_contents->IsBeingDestroyed())
old_contents->GetView()->StoreFocus();
InfoBarManager* infobar_manager =
InfoBarService::InfoBarManagerFromWebContents(new_contents);
infobar_container_->ChangeInfoBarManager(infobar_manager);
contents_container_->SetTab(new_contents);
UpdateDevToolsForContents(new_contents);
if (!browser_->tab_strip_model()->closing_all()) {
new_contents->GetView()->RestoreFocus();
FindTabHelper* find_tab_helper =
FindTabHelper::FromWebContents(new_contents);
if (find_tab_helper->find_ui_active())
browser_->GetFindBarController()->find_bar()->SetFocusAndSelection();
}
UpdateTitleBar();
MaybeShowBookmarkBar(false);
}
void BrowserWindowGtk::ZoomChangedForActiveTab(bool can_show_bubble) {
toolbar_->GetLocationBarView()->ZoomChangedForActiveTab(
can_show_bubble && !toolbar_->IsWrenchMenuShowing());
}
gfx::Rect BrowserWindowGtk::GetRestoredBounds() const {
return restored_bounds_;
}
ui::WindowShowState BrowserWindowGtk::GetRestoredState() const {
if (IsMaximized())
return ui::SHOW_STATE_MAXIMIZED;
if (IsMinimized())
return ui::SHOW_STATE_MINIMIZED;
return ui::SHOW_STATE_NORMAL;
}
gfx::Rect BrowserWindowGtk::GetBounds() const {
return bounds_;
}
bool BrowserWindowGtk::IsMaximized() const {
return (state_ & GDK_WINDOW_STATE_MAXIMIZED);
}
bool BrowserWindowGtk::IsMinimized() const {
return (state_ & GDK_WINDOW_STATE_ICONIFIED);
}
void BrowserWindowGtk::Maximize() {
gtk_window_maximize(window_);
}
void BrowserWindowGtk::Minimize() {
gtk_window_iconify(window_);
}
void BrowserWindowGtk::Restore() {
if (IsMaximized())
UnMaximize();
else if (IsMinimized())
gtk_window_deiconify(window_);
}
bool BrowserWindowGtk::ShouldDrawContentDropShadow() const {
return !IsMaximized() && UseCustomFrame();
}
void BrowserWindowGtk::EnterFullscreen(
const GURL& url, FullscreenExitBubbleType type) {
if (IsFullscreen())
return;
is_fullscreen_ = true;
gtk_window_fullscreen(window_);
browser_->WindowFullscreenStateChanged();
UpdateCustomFrame();
toolbar_->Hide();
tabstrip_->Hide();
if (bookmark_bar_.get())
gtk_widget_hide(bookmark_bar_->widget());
if (!chrome::IsRunningInAppMode()) {
UpdateFullscreenExitBubbleContent(url, type);
}
gtk_widget_hide(titlebar_widget());
gtk_widget_hide(toolbar_border_);
}
void BrowserWindowGtk::UpdateFullscreenExitBubbleContent(
const GURL& url, FullscreenExitBubbleType bubble_type) {
if (!window_) {
return;
} else if (bubble_type == FEB_TYPE_NONE) {
fullscreen_exit_bubble_.reset();
} else if (fullscreen_exit_bubble_.get()) {
fullscreen_exit_bubble_->UpdateContent(url, bubble_type);
} else {
fullscreen_exit_bubble_.reset(new FullscreenExitBubbleGtk(
GTK_FLOATING_CONTAINER(render_area_floating_container_),
browser(),
url,
bubble_type));
}
}
void BrowserWindowGtk::ExitFullscreen() {
if (!IsFullscreen())
return;
is_fullscreen_ = false;
bool unmaximize_before_unfullscreen = IsMaximized() &&
ui::GuessWindowManager() == ui::WM_METACITY;
if (unmaximize_before_unfullscreen)
UnMaximize();
gtk_window_unfullscreen(window_);
if (unmaximize_before_unfullscreen)
gtk_window_maximize(window_);
browser_->WindowFullscreenStateChanged();
gtk_widget_show(titlebar_widget());
UpdateFullscreenExitBubbleContent(GURL(), FEB_TYPE_NONE);
UpdateCustomFrame();
ShowSupportedWindowFeatures();
}
bool BrowserWindowGtk::ShouldHideUIForFullscreen() const {
return IsFullscreen();
}
bool BrowserWindowGtk::IsFullscreen() const {
return is_fullscreen_;
}
bool BrowserWindowGtk::IsFullscreenBubbleVisible() const {
return fullscreen_exit_bubble_ != NULL;
}
LocationBar* BrowserWindowGtk::GetLocationBar() const {
return toolbar_->GetLocationBar();
}
void BrowserWindowGtk::SetFocusToLocationBar(bool select_all) {
if (!IsFullscreen())
GetLocationBar()->FocusLocation(select_all);
}
void BrowserWindowGtk::UpdateReloadStopState(bool is_loading, bool force) {
toolbar_->GetReloadButton()->ChangeMode(
is_loading ? ReloadButtonGtk::MODE_STOP : ReloadButtonGtk::MODE_RELOAD,
force);
}
void BrowserWindowGtk::UpdateToolbar(content::WebContents* contents) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::UpdateToolbar");
toolbar_->UpdateWebContents(contents);
}
void BrowserWindowGtk::FocusToolbar() {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::FocusAppMenu() {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::FocusBookmarksToolbar() {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::FocusInfobars() {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::RotatePaneFocus(bool forwards) {
NOTIMPLEMENTED();
}
bool BrowserWindowGtk::IsBookmarkBarVisible() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR) &&
bookmark_bar_.get() &&
browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
}
bool BrowserWindowGtk::IsBookmarkBarAnimating() const {
if (IsBookmarkBarSupported() && bookmark_bar_->IsAnimating())
return true;
return false;
}
bool BrowserWindowGtk::IsTabStripEditable() const {
return !tabstrip()->IsDragSessionActive() &&
!tabstrip()->IsActiveDropTarget();
}
bool BrowserWindowGtk::IsToolbarVisible() const {
return IsToolbarSupported();
}
gfx::Rect BrowserWindowGtk::GetRootWindowResizerRect() const {
return gfx::Rect();
}
void BrowserWindowGtk::ConfirmAddSearchProvider(TemplateURL* template_url,
Profile* profile) {
new EditSearchEngineDialog(window_, template_url, NULL, profile);
}
void BrowserWindowGtk::ShowUpdateChromeDialog() {
UpdateRecommendedDialog::Show(window_);
}
void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url,
bool already_bookmarked) {
toolbar_->GetLocationBarView()->ShowStarBubble(url, !already_bookmarked);
}
void BrowserWindowGtk::ShowBookmarkAppBubble(
const WebApplicationInfo& web_app_info,
const std::string& extension_id) {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::ShowTranslateBubble(
content::WebContents* contents,
TranslateTabHelper::TranslateStep step,
TranslateErrors::Type error_type) {
NOTIMPLEMENTED();
}
#if defined(ENABLE_ONE_CLICK_SIGNIN)
void BrowserWindowGtk::ShowOneClickSigninBubble(
OneClickSigninBubbleType type,
const base::string16& email,
const base::string16& error_message,
const StartSyncCallback& start_sync_callback) {
new OneClickSigninBubbleGtk(this, type, email,
error_message, start_sync_callback);
}
#endif
bool BrowserWindowGtk::IsDownloadShelfVisible() const {
return download_shelf_.get() && download_shelf_->IsShowing();
}
DownloadShelf* BrowserWindowGtk::GetDownloadShelf() {
if (!download_shelf_.get())
download_shelf_.reset(new DownloadShelfGtk(browser_.get(),
render_area_vbox_));
return download_shelf_.get();
}
void BrowserWindowGtk::UserChangedTheme() {
SetBackgroundColor();
InvalidateWindow();
UpdateWindowShape(bounds_.width(), bounds_.height());
}
int BrowserWindowGtk::GetExtraRenderViewHeight() const {
int sum = infobar_container_->TotalHeightOfAnimatingBars();
if (IsBookmarkBarSupported() && bookmark_bar_->IsAnimating())
sum += bookmark_bar_->GetHeight();
if (download_shelf_.get() && download_shelf_->IsClosing())
sum += download_shelf_->GetHeight();
return sum;
}
void BrowserWindowGtk::WebContentsFocused(WebContents* contents) {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::ShowWebsiteSettings(
Profile* profile,
content::WebContents* web_contents,
const GURL& url,
const content::SSLStatus& ssl) {
WebsiteSettingsPopupGtk::Show(GetNativeWindow(), profile, web_contents, url,
ssl);
}
void BrowserWindowGtk::ShowAppMenu() {
toolbar_->ShowAppMenu();
}
bool BrowserWindowGtk::PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
GdkEventKey* os_event = &event.os_event->key;
if (!os_event || event.type != blink::WebInputEvent::RawKeyDown)
return false;
if (ExtensionKeybindingRegistryGtk::shortcut_handling_suspended())
return false;
int id = GetCustomCommandId(os_event);
if (id == -1) {
bool original_block_command_state =
browser_->command_controller()->block_command_execution();
browser_->command_controller()->SetBlockCommandExecution(true);
gtk_window_activate_key(window_, os_event);
id = browser_->command_controller()->GetLastBlockedCommand(NULL);
browser_->command_controller()->SetBlockCommandExecution(
original_block_command_state);
}
if (id == -1)
return false;
if (browser_->command_controller()->IsReservedCommandOrKey(id, event) &&
!event.match_edit_command) {
return chrome::ExecuteCommand(browser_.get(), id);
}
DCHECK(is_keyboard_shortcut != NULL);
*is_keyboard_shortcut = true;
return false;
}
void BrowserWindowGtk::HandleKeyboardEvent(
const NativeWebKeyboardEvent& event) {
GdkEventKey* os_event = &event.os_event->key;
if (!os_event || event.type != blink::WebInputEvent::RawKeyDown)
return;
int id = GetCustomCommandId(os_event);
if (id != -1)
chrome::ExecuteCommand(browser_.get(), id);
else
gtk_window_activate_key(window_, os_event);
}
void BrowserWindowGtk::Cut() {
gtk_window_util::DoCut(
window_, browser_->tab_strip_model()->GetActiveWebContents());
}
void BrowserWindowGtk::Copy() {
gtk_window_util::DoCopy(
window_, browser_->tab_strip_model()->GetActiveWebContents());
}
void BrowserWindowGtk::Paste() {
gtk_window_util::DoPaste(
window_, browser_->tab_strip_model()->GetActiveWebContents());
}
WindowOpenDisposition BrowserWindowGtk::GetDispositionForPopupBounds(
const gfx::Rect& bounds) {
return NEW_POPUP;
}
FindBar* BrowserWindowGtk::CreateFindBar() {
return new FindBarGtk(this);
}
WebContentsModalDialogHost* BrowserWindowGtk::GetWebContentsModalDialogHost() {
return NULL;
}
void BrowserWindowGtk::ShowAvatarBubble(WebContents* web_contents,
const gfx::Rect& rect) {
GtkWidget* widget = web_contents->GetView()->GetContentNativeView();
new AvatarMenuBubbleGtk(browser_.get(), widget, BubbleGtk::ANCHOR_TOP_RIGHT,
&rect);
}
void BrowserWindowGtk::ShowAvatarBubbleFromAvatarButton(AvatarBubbleMode mode) {
if (titlebar_->avatar_button())
titlebar_->avatar_button()->ShowAvatarBubble();
}
void BrowserWindowGtk::ShowPasswordGenerationBubble(
const gfx::Rect& rect,
const autofill::PasswordForm& form,
autofill::PasswordGenerator* password_generator) {
WebContents* web_contents =
browser_->tab_strip_model()->GetActiveWebContents();
if (!web_contents || !web_contents->GetView()->GetContentNativeView()) {
return;
}
new PasswordGenerationBubbleGtk(rect, form, web_contents, password_generator);
}
void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads(
int download_count,
Browser::DownloadClosePreventionType dialog_type,
bool app_modal,
const base::Callback<void(bool)>& callback) {
DownloadInProgressDialogGtk::Show(
GetNativeWindow(), download_count, dialog_type, app_modal, callback);
}
int
BrowserWindowGtk::GetRenderViewHeightInsetWithDetachedBookmarkBar() {
if (!bookmark_bar_.get() ||
browser_->bookmark_bar_state() != BookmarkBar::DETACHED) {
return 0;
}
return bookmark_bar_->max_height();
}
void BrowserWindowGtk::ExecuteExtensionCommand(
const extensions::Extension* extension,
const extensions::Command& command) {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::ShowPageActionPopup(
const extensions::Extension* extension) {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::ShowBrowserActionPopup(
const extensions::Extension* extension) {
NOTIMPLEMENTED();
}
void BrowserWindowGtk::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, type);
gtk_util::SetWindowIcon(window_, browser_->profile());
}
void BrowserWindowGtk::TabDetachedAt(WebContents* contents, int index) {
if (index == browser_->tab_strip_model()->active_index()) {
infobar_container_->ChangeInfoBarManager(NULL);
UpdateDevToolsForContents(NULL);
}
contents_container_->DetachTab(contents);
}
void BrowserWindowGtk::ActiveWindowChanged(GdkWindow* active_window) {
if (!window_)
return;
bool is_active = gtk_widget_get_window(GTK_WIDGET(window_)) == active_window;
bool changed = (is_active != is_active_);
if (is_active && changed) {
if (AppModalDialogQueue::GetInstance()->HasActiveDialog()) {
AppModalDialogQueue::GetInstance()->ActivateModalDialog();
return;
}
}
is_active_ = is_active;
if (changed) {
SetBackgroundColor();
InvalidateWindow();
UpdateWindowShape(bounds_.width(), bounds_.height());
}
}
SkColor BrowserWindowGtk::GetInfoBarSeparatorColor() const {
GtkThemeService* theme_service = GtkThemeService::GetFrom(
browser()->profile());
return gfx::GdkColorToSkColor(theme_service->GetBorderColor());
}
void BrowserWindowGtk::InfoBarContainerStateChanged(bool is_animating) {
InvalidateInfoBarBits();
}
bool BrowserWindowGtk::DrawInfoBarArrows(int* x) const {
if (x) {
*x = 0;
NOTREACHED();
}
return true;
}
extensions::ActiveTabPermissionGranter*
BrowserWindowGtk::GetActiveTabPermissionGranter() {
WebContents* tab = GetDisplayedTab();
if (!tab)
return NULL;
return extensions::TabHelper::FromWebContents(tab)->
active_tab_permission_granter();
}
void BrowserWindowGtk::DestroyBrowser() {
browser_.reset();
}
gboolean BrowserWindowGtk::OnConfigure(GtkWidget* widget,
GdkEventConfigure* event) {
gfx::Rect bounds(event->x, event->y, event->width, event->height);
if (bounds == configure_bounds_)
return FALSE;
GetLocationBar()->GetOmniboxView()->CloseOmniboxPopup();
WebContents* tab = GetDisplayedTab();
if (tab)
tab->GetRenderViewHost()->NotifyMoveOrResizeStarted();
if (bounds_.size() != bounds.size())
UpdateWindowShape(bounds.width(), bounds.height());
bounds_ = bounds;
configure_bounds_ = bounds;
window_configure_debounce_timer_.Stop();
window_configure_debounce_timer_.Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kDebounceTimeoutMilliseconds), this,
&BrowserWindowGtk::OnDebouncedBoundsChanged);
return FALSE;
}
void BrowserWindowGtk::OnDebouncedBoundsChanged() {
gtk_window_util::UpdateWindowPosition(this, &bounds_, &restored_bounds_);
SaveWindowPosition();
}
gboolean BrowserWindowGtk::OnWindowState(GtkWidget* sender,
GdkEventWindowState* event) {
state_ = event->new_window_state;
if (event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) {
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_BROWSER_WINDOW_MAXIMIZED,
content::Source<BrowserWindow>(this),
content::NotificationService::NoDetails());
}
titlebar_->UpdateCustomFrame(UseCustomFrame() && !IsFullscreen());
UpdateWindowShape(bounds_.width(), bounds_.height());
SaveWindowPosition();
return FALSE;
}
gboolean BrowserWindowGtk::OnMainWindowDeleteEvent(GtkWidget* widget,
GdkEvent* event) {
Close();
return TRUE;
}
void BrowserWindowGtk::OnMainWindowDestroy(GtkWidget* widget) {
extension_keybinding_registry_.reset();
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(&base::DeletePointer<BrowserWindowGtk>, this));
}
void BrowserWindowGtk::UnMaximize() {
gtk_window_util::UnMaximize(window_, bounds_, restored_bounds_);
}
bool BrowserWindowGtk::CanClose() const {
if (tabstrip_->IsDragSessionActive())
return false;
if (!browser_->ShouldCloseWindow())
return false;
bool fast_tab_closing_enabled =
CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableFastUnload);
if (!browser_->tab_strip_model()->empty()) {
gtk_widget_hide(GTK_WIDGET(window_));
browser_->OnWindowClosing();
if (fast_tab_closing_enabled)
browser_->tab_strip_model()->CloseAllTabs();
return false;
} else if (fast_tab_closing_enabled &&
!browser_->HasCompletedUnloadProcessing()) {
gtk_widget_hide(GTK_WIDGET(window_));
return false;
}
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_WINDOW_CLOSED,
content::Source<GtkWindow>(window_),
content::NotificationService::NoDetails());
return true;
}
bool BrowserWindowGtk::ShouldShowWindowIcon() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR);
}
void BrowserWindowGtk::AddFindBar(FindBarGtk* findbar) {
gtk_floating_container_add_floating(
GTK_FLOATING_CONTAINER(render_area_floating_container_),
findbar->widget());
}
void BrowserWindowGtk::ResetCustomFrameCursor() {
if (!frame_cursor_)
return;
frame_cursor_ = NULL;
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)), NULL);
}
BrowserWindowGtk* BrowserWindowGtk::GetBrowserWindowForNativeWindow(
gfx::NativeWindow window) {
if (window) {
return static_cast<BrowserWindowGtk*>(
g_object_get_qdata(G_OBJECT(window), GetBrowserWindowQuarkKey()));
}
return NULL;
}
GtkWindow* BrowserWindowGtk::GetBrowserWindowForXID(XID xid) {
GtkWindow* window = ui::GetGtkWindowFromX11Window(xid);
if (!GetBrowserWindowForNativeWindow(window))
return NULL;
return window;
}
GtkWidget* BrowserWindowGtk::titlebar_widget() const {
return titlebar_->widget();
}
void BrowserWindowGtk::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
bool custom_frame_default = false;
if (ui::XDisplayExists())
custom_frame_default = ui::GetCustomFramePrefDefault();
registry->RegisterBooleanPref(
prefs::kUseCustomChromeFrame,
custom_frame_default,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
WebContents* BrowserWindowGtk::GetDisplayedTab() {
return contents_container_->tab();
}
void BrowserWindowGtk::QueueToolbarRedraw() {
gtk_widget_queue_draw(toolbar_->widget());
}
void BrowserWindowGtk::SetGeometryHints() {
gfx::Rect bounds;
chrome::GetSavedWindowBoundsAndShowState(browser_.get(),
&bounds,
&show_state_after_show_);
bool is_popup = browser_->is_type_popup();
bool popup_without_position = is_popup &&
bounds.x() == 0 && bounds.y() == 0;
bool move = browser_->bounds_overridden() && !popup_without_position;
SetBoundsImpl(bounds, !is_popup, move);
}
void BrowserWindowGtk::ConnectHandlersToSignals() {
g_signal_connect(window_, "delete-event",
G_CALLBACK(OnMainWindowDeleteEventThunk), this);
g_signal_connect(window_, "destroy",
G_CALLBACK(OnMainWindowDestroyThunk), this);
g_signal_connect(window_, "configure-event",
G_CALLBACK(OnConfigureThunk), this);
g_signal_connect(window_, "window-state-event",
G_CALLBACK(OnWindowStateThunk), this);
g_signal_connect(window_, "key-press-event",
G_CALLBACK(OnKeyPressThunk), this);
g_signal_connect(window_, "motion-notify-event",
G_CALLBACK(OnMouseMoveEventThunk), this);
g_signal_connect(window_, "button-press-event",
G_CALLBACK(OnButtonPressEventThunk), this);
g_signal_connect(window_, "focus-in-event",
G_CALLBACK(OnFocusInThunk), this);
g_signal_connect(window_, "focus-out-event",
G_CALLBACK(OnFocusOutThunk), this);
}
void BrowserWindowGtk::InitWidgets() {
ConnectHandlersToSignals();
bounds_ = configure_bounds_ = restored_bounds_ =
GetInitialWindowBounds(window_);
window_vbox_ = gtk_vbox_new(FALSE, 0);
gtk_widget_show(window_vbox_);
global_menu_bar_.reset(new GlobalMenuBar(browser_.get()));
gtk_container_add(GTK_CONTAINER(window_vbox_), global_menu_bar_->widget());
window_container_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
gtk_widget_set_name(window_container_, "chrome-custom-frame-border");
gtk_widget_set_app_paintable(window_container_, TRUE);
gtk_widget_set_double_buffered(window_container_, FALSE);
gtk_widget_set_redraw_on_allocate(window_container_, TRUE);
g_signal_connect(window_container_, "expose-event",
G_CALLBACK(OnCustomFrameExposeThunk), this);
gtk_container_add(GTK_CONTAINER(window_container_), window_vbox_);
tabstrip_.reset(new TabStripGtk(browser_->tab_strip_model(), this));
tabstrip_->Init();
titlebar_.reset(new BrowserTitlebar(this, window_));
titlebar_->Init();
gtk_box_pack_start(GTK_BOX(window_vbox_), titlebar_->widget(), FALSE, FALSE,
0);
toolbar_.reset(new BrowserToolbarGtk(browser_.get(), this));
toolbar_->Init(window_);
gtk_box_pack_start(GTK_BOX(window_vbox_), toolbar_->widget(),
FALSE, FALSE, 0);
g_signal_connect_after(toolbar_->widget(), "expose-event",
G_CALLBACK(OnExposeDrawInfobarBitsThunk), this);
render_area_vbox_ = gtk_vbox_new(FALSE, 0);
gtk_widget_set_name(render_area_vbox_, "chrome-render-area-vbox");
render_area_floating_container_ = gtk_floating_container_new();
gtk_container_add(GTK_CONTAINER(render_area_floating_container_),
render_area_vbox_);
GtkWidget* location_icon = toolbar_->GetLocationBarView()->
location_icon_widget();
g_signal_connect(location_icon, "size-allocate",
G_CALLBACK(OnLocationIconSizeAllocateThunk), this);
g_signal_connect_after(location_icon, "expose-event",
G_CALLBACK(OnExposeDrawInfobarBitsThunk), this);
toolbar_border_ = gtk_event_box_new();
gtk_box_pack_start(GTK_BOX(render_area_vbox_),
toolbar_border_, FALSE, FALSE, 0);
gtk_widget_set_size_request(toolbar_border_, -1, 1);
gtk_widget_set_no_show_all(toolbar_border_, TRUE);
g_signal_connect_after(toolbar_border_, "expose-event",
G_CALLBACK(OnExposeDrawInfobarBitsThunk), this);
if (IsToolbarSupported())
gtk_widget_show(toolbar_border_);
infobar_container_.reset(
new InfoBarContainerGtk(this, browser_->profile()));
gtk_box_pack_start(GTK_BOX(render_area_vbox_),
infobar_container_->widget(),
FALSE, FALSE, 0);
status_bubble_.reset(new StatusBubbleGtk(browser_->profile()));
contents_container_.reset(new TabContentsContainerGtk(
status_bubble_.get(),
implicit_cast<content::WebContentsDelegate*>(browser_.get())->
EmbedsFullscreenWidget()));
devtools_container_.reset(new TabContentsContainerGtk(NULL, false));
ViewIDUtil::SetDelegateForWidget(devtools_container_->widget(), NULL);
ViewIDUtil::SetID(devtools_container_->widget(), VIEW_ID_DEV_TOOLS_DOCKED);
devtools_floating_container_ = gtk_floating_container_new();
gtk_container_add(GTK_CONTAINER(devtools_floating_container_),
devtools_container_->widget());
gtk_floating_container_add_floating(
GTK_FLOATING_CONTAINER(devtools_floating_container_),
contents_container_->widget());
g_signal_connect(devtools_floating_container_, "set-floating-position",
G_CALLBACK(OnDevToolsContainerSetFloatingPosition), this);
gtk_box_pack_end(GTK_BOX(render_area_vbox_),
devtools_floating_container_, TRUE, TRUE, 0);
gtk_widget_show_all(render_area_floating_container_);
render_area_event_box_ = gtk_event_box_new();
gtk_widget_modify_bg(render_area_event_box_, GTK_STATE_NORMAL,
&ui::kGdkWhite);
gtk_container_add(GTK_CONTAINER(render_area_event_box_),
render_area_floating_container_);
gtk_widget_show(render_area_event_box_);
gtk_box_pack_end(GTK_BOX(window_vbox_), render_area_event_box_,
TRUE, TRUE, 0);
if (IsBookmarkBarSupported()) {
bookmark_bar_.reset(new BookmarkBarGtk(this,
browser_.get(),
tabstrip_.get()));
PlaceBookmarkBar(false);
gtk_widget_show(bookmark_bar_->widget());
g_signal_connect_after(bookmark_bar_->widget(), "expose-event",
G_CALLBACK(OnBookmarkBarExposeThunk), this);
g_signal_connect(bookmark_bar_->widget(), "size-allocate",
G_CALLBACK(OnBookmarkBarSizeAllocateThunk), this);
}
gtk_widget_realize(GTK_WIDGET(window_));
state_ = gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(window_)));
UpdateCustomFrame();
extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryGtk(
browser_->profile(),
window_,
extensions::ExtensionKeybindingRegistry::ALL_EXTENSIONS,
this));
static bool default_icon_set = false;
if (!default_icon_set) {
gtk_util::SetDefaultWindowIcon(window_);
default_icon_set = true;
}
gtk_util::SetWindowIcon(window_, browser_->profile());
gtk_container_add(GTK_CONTAINER(window_), window_container_);
gtk_widget_show(window_container_);
browser_->tab_strip_model()->AddObserver(this);
}
void BrowserWindowGtk::SetBackgroundColor() {
Profile* profile = browser()->profile();
GtkThemeService* theme_provider = GtkThemeService::GetFrom(profile);
int frame_color_id;
if (UsingCustomPopupFrame()) {
frame_color_id = ThemeProperties::COLOR_TOOLBAR;
} else if (DrawFrameAsActive()) {
frame_color_id = browser()->profile()->IsOffTheRecord()
? ThemeProperties::COLOR_FRAME_INCOGNITO
: ThemeProperties::COLOR_FRAME;
} else {
frame_color_id = browser()->profile()->IsOffTheRecord()
? ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE
: ThemeProperties::COLOR_FRAME_INACTIVE;
}
SkColor frame_color = theme_provider->GetColor(frame_color_id);
GdkColor frame_color_gdk = gfx::SkColorToGdkColor(frame_color);
gtk_widget_modify_bg(GTK_WIDGET(window_), GTK_STATE_NORMAL,
&frame_color_gdk);
GdkColor border_color = theme_provider->GetBorderColor();
gtk_widget_modify_bg(toolbar_border_, GTK_STATE_NORMAL, &border_color);
}
void BrowserWindowGtk::UpdateWindowShape(int width, int height) {
using gtk_window_util::kFrameBorderThickness;
GdkRegion* mask = GetWindowShape(width, height);
gdk_window_shape_combine_region(
gtk_widget_get_window(GTK_WIDGET(window_)), mask, 0, 0);
if (mask)
gdk_region_destroy(mask);
if (UseCustomFrame() && !IsFullscreen() && !IsMaximized()) {
gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 1,
kFrameBorderThickness, kFrameBorderThickness, kFrameBorderThickness);
} else {
gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0);
}
}
GdkRegion* BrowserWindowGtk::GetWindowShape(int width, int height) const {
if (UseCustomFrame() && !IsFullscreen() && !IsMaximized()) {
GdkRectangle top_top_rect = { 3, 0, width - 6, 1 };
GdkRectangle top_mid_rect = { 1, 1, width - 2, 2 };
GdkRectangle mid_rect = { 0, 3, width, height - 6 };
GdkRectangle bot_mid_rect = top_mid_rect;
bot_mid_rect.y = height - 3;
GdkRectangle bot_bot_rect = top_top_rect;
bot_bot_rect.y = height - 1;
GdkRegion* mask = gdk_region_rectangle(&top_top_rect);
gdk_region_union_with_rect(mask, &top_mid_rect);
gdk_region_union_with_rect(mask, &mid_rect);
gdk_region_union_with_rect(mask, &bot_mid_rect);
gdk_region_union_with_rect(mask, &bot_bot_rect);
return mask;
} else if (UseCustomFrame()) {
GdkRectangle rect = { 0, 0, width, height };
GdkRegion* mask = gdk_region_rectangle(&rect);
return mask;
} else {
return NULL;
}
}
void BrowserWindowGtk::ConnectAccelerators() {
accel_group_ = gtk_accel_group_new();
gtk_window_add_accel_group(window_, accel_group_);
AcceleratorsGtk* accelerators = AcceleratorsGtk::GetInstance();
for (AcceleratorsGtk::const_iterator iter = accelerators->begin();
iter != accelerators->end(); ++iter) {
gtk_accel_group_connect(
accel_group_,
ui::GetGdkKeyCodeForAccelerator(iter->second),
ui::GetGdkModifierForAccelerator(iter->second),
GtkAccelFlags(0),
g_cclosure_new(G_CALLBACK(OnGtkAccelerator),
GINT_TO_POINTER(iter->first), NULL));
}
}
void BrowserWindowGtk::UpdateCustomFrame() {
gtk_window_set_decorated(window_, !UseCustomFrame());
titlebar_->UpdateCustomFrame(UseCustomFrame() && !IsFullscreen());
UpdateWindowShape(bounds_.width(), bounds_.height());
}
void BrowserWindowGtk::InvalidateWindow() {
GtkAllocation allocation;
gtk_widget_get_allocation(GTK_WIDGET(window_), &allocation);
gdk_window_invalidate_rect(gtk_widget_get_window(GTK_WIDGET(window_)),
&allocation, TRUE);
}
void BrowserWindowGtk::SaveWindowPosition() {
ui::WindowShowState show_state = ui::SHOW_STATE_NORMAL;
if (IsMaximized())
show_state = ui::SHOW_STATE_MAXIMIZED;
else if (IsMinimized())
show_state = ui::SHOW_STATE_MINIMIZED;
if (chrome::ShouldSaveWindowPlacement(browser_.get()))
chrome::SaveWindowPlacement(browser_.get(), restored_bounds_, show_state);
if (!browser_->profile()->GetPrefs())
return;
std::string window_name = chrome::GetWindowPlacementKey(browser_.get());
DictionaryPrefUpdate update(browser_->profile()->GetPrefs(),
window_name.c_str());
base::DictionaryValue* window_preferences = update.Get();
window_preferences->SetInteger("left", restored_bounds_.x());
window_preferences->SetInteger("top", restored_bounds_.y());
window_preferences->SetInteger("right", restored_bounds_.right());
window_preferences->SetInteger("bottom", restored_bounds_.bottom());
window_preferences->SetBoolean("maximized", IsMaximized());
gfx::Rect work_area(gfx::Screen::GetNativeScreen()->GetDisplayMatching(
restored_bounds_).work_area());
window_preferences->SetInteger("work_area_left", work_area.x());
window_preferences->SetInteger("work_area_top", work_area.y());
window_preferences->SetInteger("work_area_right", work_area.right());
window_preferences->SetInteger("work_area_bottom", work_area.bottom());
}
void BrowserWindowGtk::InvalidateInfoBarBits() {
gtk_widget_queue_draw(toolbar_border_);
gtk_widget_queue_draw(toolbar_->widget());
if (bookmark_bar_.get() &&
browser_->bookmark_bar_state() != BookmarkBar::DETACHED) {
gtk_widget_queue_draw(bookmark_bar_->widget());
}
}
int BrowserWindowGtk::GetXPositionOfLocationIcon(GtkWidget* relative_to) {
GtkWidget* location_icon = toolbar_->GetLocationBarView()->
location_icon_widget();
GtkAllocation location_icon_allocation;
gtk_widget_get_allocation(location_icon, &location_icon_allocation);
int x = 0;
gtk_widget_translate_coordinates(
location_icon, relative_to,
(location_icon_allocation.width + 1) / 2,
0, &x, NULL);
if (!gtk_widget_get_has_window(relative_to)) {
GtkAllocation allocation;
gtk_widget_get_allocation(relative_to, &allocation);
x += allocation.x;
}
return x;
}
void BrowserWindowGtk::MaybeShowBookmarkBar(bool animate) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::MaybeShowBookmarkBar");
if (!IsBookmarkBarSupported())
return;
if (GetDisplayedTab())
bookmark_bar_->SetPageNavigator(browser_.get());
BookmarkBar::State state = browser_->bookmark_bar_state();
toolbar_->UpdateForBookmarkBarVisibility(state == BookmarkBar::DETACHED);
PlaceBookmarkBar(state == BookmarkBar::DETACHED);
bookmark_bar_->SetBookmarkBarState(
state,
animate ? BookmarkBar::ANIMATE_STATE_CHANGE :
BookmarkBar::DONT_ANIMATE_STATE_CHANGE);
}
void BrowserWindowGtk::OnLocationIconSizeAllocate(GtkWidget* sender,
GtkAllocation* allocation) {
InvalidateInfoBarBits();
}
gboolean BrowserWindowGtk::OnExposeDrawInfobarBits(GtkWidget* sender,
GdkEventExpose* expose) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::OnExposeDrawInfobarBits");
infobar_container_->PaintInfobarBitsOn(sender, expose, NULL);
return FALSE;
}
gboolean BrowserWindowGtk::OnBookmarkBarExpose(GtkWidget* sender,
GdkEventExpose* expose) {
if (browser_->bookmark_bar_state() == BookmarkBar::DETACHED)
return FALSE;
return OnExposeDrawInfobarBits(sender, expose);
}
void BrowserWindowGtk::OnBookmarkBarSizeAllocate(GtkWidget* sender,
GtkAllocation* allocation) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::OnBookmarkBarSizeAllocate");
if (infobar_container_->ContainsInfobars())
InvalidateInfoBarBits();
int arrow_size = InfoBar::kDefaultArrowTargetHeight;
if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED)
arrow_size += allocation->height;
infobar_container_->SetMaxTopArrowHeight(arrow_size);
}
gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group,
GObject* acceleratable,
guint keyval,
GdkModifierType modifier,
void* user_data) {
int command_id = GPOINTER_TO_INT(user_data);
BrowserWindowGtk* browser_window =
GetBrowserWindowForNativeWindow(GTK_WINDOW(acceleratable));
DCHECK(browser_window != NULL);
return chrome::ExecuteCommand(browser_window->browser(), command_id);
}
gboolean BrowserWindowGtk::OnKeyPress(GtkWidget* widget, GdkEventKey* event) {
if (extension_keybinding_registry_->HasPriorityHandler(event))
return FALSE;
WebContents* current_web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
if (!current_web_contents ||
!current_web_contents->GetView()->GetContentNativeView() ||
!gtk_widget_is_focus(
current_web_contents->GetView()->GetContentNativeView())) {
int command_id = GetCustomCommandId(event);
if (command_id == -1)
command_id = GetPreHandleCommandId(event);
if (command_id != -1 && chrome::ExecuteCommand(browser_.get(), command_id))
return TRUE;
if (!gtk_window_propagate_key_event(GTK_WINDOW(widget), event)) {
if (!gtk_window_activate_key(GTK_WINDOW(widget), event)) {
gtk_bindings_activate_event(GTK_OBJECT(widget), event);
}
}
} else {
bool rv = gtk_window_propagate_key_event(GTK_WINDOW(widget), event);
DCHECK(rv);
}
return TRUE;
}
gboolean BrowserWindowGtk::OnMouseMoveEvent(GtkWidget* widget,
GdkEventMotion* event) {
if (!UseCustomFrame() || event->window != gtk_widget_get_window(widget)) {
if (frame_cursor_) {
frame_cursor_ = NULL;
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)), NULL);
}
return FALSE;
}
GdkWindowEdge edge;
bool has_hit_edge = GetWindowEdge(static_cast<int>(event->x),
static_cast<int>(event->y), &edge);
GdkCursorType new_cursor = GDK_LAST_CURSOR;
if (has_hit_edge)
new_cursor = gtk_window_util::GdkWindowEdgeToGdkCursorType(edge);
GdkCursorType last_cursor = GDK_LAST_CURSOR;
if (frame_cursor_)
last_cursor = frame_cursor_->type;
if (last_cursor != new_cursor) {
if (has_hit_edge) {
frame_cursor_ = gfx::GetCursor(new_cursor);
} else {
frame_cursor_ = NULL;
}
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(window_)),
frame_cursor_);
}
return FALSE;
}
gboolean BrowserWindowGtk::OnButtonPressEvent(GtkWidget* widget,
GdkEventButton* event) {
if (event->type == GDK_BUTTON_PRESS) {
if (event->button == 8) {
chrome::GoBack(browser_.get(), CURRENT_TAB);
return TRUE;
} else if (event->button == 9) {
chrome::GoForward(browser_.get(), CURRENT_TAB);
return TRUE;
}
}
int win_x, win_y;
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_));
gdk_window_get_origin(gdk_window, &win_x, &win_y);
GdkWindowEdge edge;
gfx::Point point(static_cast<int>(event->x_root - win_x),
static_cast<int>(event->y_root - win_y));
bool has_hit_edge = GetWindowEdge(point.x(), point.y(), &edge);
GtkWidget* toolbar = toolbar_->widget();
if (!gtk_widget_get_visible(toolbar)) {
toolbar = render_area_vbox_;
}
gint toolbar_y;
gtk_widget_get_pointer(toolbar, NULL, &toolbar_y);
bool has_hit_titlebar = !IsFullscreen() && (toolbar_y < 0)
&& !has_hit_edge;
if (event->button == 1) {
if (GDK_BUTTON_PRESS == event->type) {
if ((has_hit_titlebar || has_hit_edge) && !suppress_window_raise_)
gdk_window_raise(gdk_window);
if (has_hit_titlebar) {
return gtk_window_util::HandleTitleBarLeftMousePress(
window_, bounds_, event);
} else if (has_hit_edge) {
gtk_window_begin_resize_drag(window_, edge, event->button,
static_cast<gint>(event->x_root),
static_cast<gint>(event->y_root),
event->time);
return TRUE;
}
} else if (GDK_2BUTTON_PRESS == event->type) {
if (has_hit_titlebar) {
if (IsMaximized()) {
UnMaximize();
} else {
gtk_window_maximize(window_);
}
return TRUE;
}
}
} else if (event->button == 2) {
if (has_hit_titlebar || has_hit_edge) {
gdk_window_lower(gdk_window);
}
return TRUE;
} else if (event->button == 3) {
if (has_hit_titlebar) {
titlebar_->ShowContextMenu(event);
return TRUE;
}
}
return FALSE;
}
gboolean BrowserWindowGtk::OnFocusIn(GtkWidget* widget,
GdkEventFocus* event) {
BrowserList::SetLastActive(browser_.get());
return FALSE;
}
gboolean BrowserWindowGtk::OnFocusOut(GtkWidget* widget,
GdkEventFocus* event) {
return FALSE;
}
void BrowserWindowGtk::ShowSupportedWindowFeatures() {
if (IsTabStripSupported())
tabstrip_->Show();
if (IsToolbarSupported()) {
toolbar_->Show();
gtk_widget_show(toolbar_border_);
gdk_window_lower(gtk_widget_get_window(toolbar_border_));
}
if (IsBookmarkBarSupported())
MaybeShowBookmarkBar(false);
}
void BrowserWindowGtk::HideUnsupportedWindowFeatures() {
if (!IsTabStripSupported())
tabstrip_->Hide();
if (!IsToolbarSupported())
toolbar_->Hide();
}
bool BrowserWindowGtk::IsTabStripSupported() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
}
bool BrowserWindowGtk::IsToolbarSupported() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
}
bool BrowserWindowGtk::IsBookmarkBarSupported() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR);
}
bool BrowserWindowGtk::UsingCustomPopupFrame() const {
GtkThemeService* theme_provider = GtkThemeService::GetFrom(
browser()->profile());
return !theme_provider->UsingNativeTheme() && browser()->is_type_popup();
}
bool BrowserWindowGtk::GetWindowEdge(int x, int y, GdkWindowEdge* edge) {
if (!UseCustomFrame())
return false;
if (IsMaximized() || IsFullscreen())
return false;
return gtk_window_util::GetWindowEdge(
bounds_.size(), kTopResizeAdjust, x, y, edge);
}
bool BrowserWindowGtk::UseCustomFrame() const {
return use_custom_frame_pref_.GetValue() && !browser_->is_app();
}
void BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::PlaceBookmarkBar");
GtkWidget* target_parent = NULL;
if (!is_floating) {
target_parent = window_vbox_;
} else {
target_parent = render_area_vbox_;
}
GtkWidget* parent = gtk_widget_get_parent(bookmark_bar_->widget());
if (parent != target_parent) {
if (parent)
gtk_container_remove(GTK_CONTAINER(parent), bookmark_bar_->widget());
gtk_box_pack_end(GTK_BOX(target_parent), bookmark_bar_->widget(),
FALSE, FALSE, 0);
}
}
bool BrowserWindowGtk::DrawFrameAsActive() const {
if (ui::ActiveWindowWatcherX::WMSupportsActivation())
return is_active_;
return true;
}
void BrowserWindowGtk::UpdateDevToolsForContents(WebContents* contents) {
TRACE_EVENT0("ui::gtk", "BrowserWindowGtk::UpdateDevToolsForContents");
DevToolsWindow* new_devtools_window = contents ?
DevToolsWindow::GetDockedInstanceForInspectedTab(contents) : NULL;
if (devtools_window_ != new_devtools_window) {
if (devtools_window_)
devtools_container_->DetachTab(devtools_window_->web_contents());
devtools_container_->SetTab(
new_devtools_window ? new_devtools_window->web_contents() : NULL);
if (new_devtools_window) {
new_devtools_window->web_contents()->WasShown();
}
}
bool should_hide = devtools_window_ && !new_devtools_window;
bool should_show = new_devtools_window && !devtools_window_;
if (should_hide)
HideDevToolsContainer();
devtools_window_ = new_devtools_window;
if (devtools_window_) {
contents_resizing_strategy_.CopyFrom(
devtools_window_->GetContentsResizingStrategy());
} else {
contents_resizing_strategy_.CopyFrom(DevToolsContentsResizingStrategy());
}
if (should_show)
ShowDevToolsContainer();
gtk_widget_queue_resize(devtools_floating_container_);
gtk_widget_queue_draw(devtools_floating_container_);
}
void BrowserWindowGtk::ShowDevToolsContainer() {
GdkWindow* const devtools_gdk_window =
gtk_widget_get_window(devtools_container_->widget());
if (devtools_gdk_window)
gdk_window_lower(devtools_gdk_window);
}
void BrowserWindowGtk::HideDevToolsContainer() {
}
void BrowserWindowGtk::OnDevToolsContainerSetFloatingPosition(
GtkFloatingContainer* container, GtkAllocation* allocation,
BrowserWindowGtk* browser_window) {
GtkAllocation contents_allocation;
gtk_widget_get_allocation(browser_window->contents_container_->widget(),
&contents_allocation);
gfx::Size container_size(allocation->width, allocation->height);
gfx::Rect old_devtools_bounds(0, 0, allocation->width, allocation->height);
gfx::Rect old_contents_bounds(contents_allocation.x, contents_allocation.y,
contents_allocation.width, contents_allocation.height);
gfx::Rect new_devtools_bounds;
gfx::Rect new_contents_bounds;
ApplyDevToolsContentsResizingStrategy(
browser_window->contents_resizing_strategy_, container_size,
old_devtools_bounds, old_contents_bounds,
&new_devtools_bounds, &new_contents_bounds);
gtk_widget_set_size_request(browser_window->contents_container_->widget(),
new_contents_bounds.width(), new_contents_bounds.height());
GValue value = { 0, };
g_value_init(&value, G_TYPE_INT);
g_value_set_int(&value, new_contents_bounds.x());
gtk_container_child_set_property(GTK_CONTAINER(container),
browser_window->contents_container_->widget(), "x", &value);
g_value_set_int(&value, new_contents_bounds.y());
gtk_container_child_set_property(GTK_CONTAINER(container),
browser_window->contents_container_->widget(), "y", &value);
g_value_unset(&value);
}
void BrowserWindowGtk::OnUseCustomChromeFrameChanged() {
UpdateCustomFrame();
ui::SetHideTitlebarWhenMaximizedProperty(
ui::GetX11WindowFromGtkWidget(GTK_WIDGET(window_)),
UseCustomFrame() ? ui::HIDE_TITLEBAR_WHEN_MAXIMIZED :
ui::SHOW_TITLEBAR_WHEN_MAXIMIZED);
}
BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
BrowserWindowGtk* browser_window_gtk = new BrowserWindowGtk(browser);
browser_window_gtk->Init();
return browser_window_gtk;
}
chrome::HostDesktopType BrowserWindow::AdjustHostDesktopType(
chrome::HostDesktopType desktop_type) {
return desktop_type;
}