summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authordavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 00:41:04 +0000
committerdavemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-07 00:41:04 +0000
commitd904bc88427330a9cf4a32f3129c2353736be5ab (patch)
treefc4a3bd31be8bbc7ae8ed77dc1e2431963aa0bf2 /chrome/browser
parent3c78ae92e0c9a8c1e3e33c68df8e8a8af7d76a6c (diff)
downloadchromium_src-d904bc88427330a9cf4a32f3129c2353736be5ab.zip
chromium_src-d904bc88427330a9cf4a32f3129c2353736be5ab.tar.gz
chromium_src-d904bc88427330a9cf4a32f3129c2353736be5ab.tar.bz2
Popup changes
Review URL: http://codereview.chromium.org/155075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20001 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/browser.cc8
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc45
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h9
-rwxr-xr-xchrome/browser/gtk/tabs/tab_strip_gtk.cc2
-rw-r--r--chrome/browser/views/panel_controller.cc237
-rw-r--r--chrome/browser/views/panel_controller.h104
6 files changed, 394 insertions, 11 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index ea81a21..b1d5f72 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -444,16 +444,16 @@ std::wstring Browser::GetCurrentPageTitle() const {
if (title.empty())
title = l10n_util::GetString(IDS_TAB_UNTITLED_TITLE);
-#if defined(OS_WIN) || defined(OS_LINUX)
+#if defined(OS_MACOSX) || defined(LINUX2)
+ // On Mac, we don't want to suffix the page title with the application name.
+ return title;
+#elif defined(OS_WIN) || defined(OS_LINUX)
int string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT;
// Don't append the app name to window titles when we're not displaying a
// distributor logo for the frame.
if (!ShouldShowDistributorLogo())
string_id = IDS_BROWSER_WINDOW_TITLE_FORMAT_NO_LOGO;
return l10n_util::GetStringF(string_id, title);
-#elif defined(OS_MACOSX)
- // On Mac, we don't want to suffix the page title with the application name.
- return title;
#endif
}
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 5416814..44274b1 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -56,6 +56,7 @@
#include "grit/theme_resources.h"
#if defined(LINUX2)
+#include "chrome/browser/views/panel_controller.h"
#include "chrome/browser/views/tabs/tab_overview_types.h"
#endif
@@ -359,6 +360,7 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
full_screen_(false),
#if defined(LINUX2)
drag_active_(false),
+ panel_controller_(NULL),
#endif
frame_cursor_(NULL) {
use_custom_frame_.Init(prefs::kUseCustomChromeFrame,
@@ -456,8 +458,6 @@ gboolean BrowserWindowGtk::OnCustomFrameExpose(GtkWidget* widget,
}
void BrowserWindowGtk::Show() {
- gtk_widget_show(GTK_WIDGET(window_));
-
// The Browser associated with this browser window must become the active
// browser at the time Show() is called. This is the natural behaviour under
// Windows, but gtk_widget_show won't show the widget (and therefore won't
@@ -467,10 +467,17 @@ void BrowserWindowGtk::Show() {
BrowserList::SetLastActive(browser());
#if defined(LINUX2)
- TabOverviewTypes::instance()->SetWindowType(
- GTK_WIDGET(window_), TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL,
- NULL);
+ if (browser_->type() == Browser::TYPE_POPUP) {
+ panel_controller_ = new PanelController(this);
+ } else {
+ TabOverviewTypes::instance()->SetWindowType(
+ GTK_WIDGET(window_),
+ TabOverviewTypes::WINDOW_TYPE_CHROME_TOPLEVEL,
+ NULL);
+ }
#endif
+
+ gtk_widget_show(GTK_WIDGET(window_));
}
void BrowserWindowGtk::SetBounds(const gfx::Rect& bounds) {
@@ -498,6 +505,12 @@ void BrowserWindowGtk::Close() {
// destruction, set window_ to NULL before any handlers will run.
window_ = NULL;
gtk_widget_destroy(window);
+
+#if defined(LINUX2)
+ if (panel_controller_) {
+ panel_controller_->Close();
+ }
+#endif
}
void BrowserWindowGtk::Activate() {
@@ -533,6 +546,11 @@ void BrowserWindowGtk::SelectedTabToolbarSizeChanged(bool is_animating) {
}
void BrowserWindowGtk::UpdateTitleBar() {
+#if defined(LINUX2)
+ if (panel_controller_)
+ panel_controller_->UpdateTitleBar();
+#endif
+
std::wstring title = browser_->GetCurrentPageTitle();
gtk_window_set_title(window_, WideToUTF8(title).c_str());
if (ShouldShowWindowIcon()) {
@@ -1003,7 +1021,14 @@ void BrowserWindowGtk::InitWidgets() {
toolbar_.reset(new BrowserToolbarGtk(browser_.get(), this));
toolbar_->Init(browser_->profile(), window_);
- toolbar_->AddToolbarToBox(content_vbox_);
+ bool hide_tools = false;
+#if defined(LINUX2)
+ if (browser_->type() == Browser::TYPE_POPUP)
+ hide_tools = true;
+#endif
+
+ if (!hide_tools)
+ toolbar_->AddToolbarToBox(content_vbox_);
bookmark_bar_.reset(new BookmarkBarGtk(browser_->profile(), browser_.get(),
this));
@@ -1026,6 +1051,14 @@ void BrowserWindowGtk::InitWidgets() {
contents_container_->AddContainerToBox(render_area_vbox_);
gtk_widget_show_all(render_area_vbox_);
+#if defined(LINUX2)
+ if (browser_->type() == Browser::TYPE_POPUP) {
+ // The window manager needs the min size for popups
+ gtk_widget_set_size_request(
+ GTK_WIDGET(window_), bounds_.width(), bounds_.height());
+ }
+#endif
+
// We have to realize the window before we try to apply a window shape mask.
gtk_widget_realize(GTK_WIDGET(window_));
state_ = gdk_window_get_state(GTK_WIDGET(window_)->window);
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 64d4449..3045236 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -12,6 +12,7 @@
#include "base/gfx/rect.h"
#include "base/scoped_ptr.h"
#include "base/timer.h"
+#include "build/build_config.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/common/notification_registrar.h"
@@ -31,6 +32,10 @@ class StatusBubbleGtk;
class TabContentsContainerGtk;
class TabStripGtk;
+#ifdef LINUX2
+class PanelController;
+#endif
+
// An implementation of BrowserWindow for GTK.
// Cross-platform code will interact with this object when
// it needs to manipulate the window.
@@ -149,6 +154,8 @@ class BrowserWindowGtk : public BrowserWindow,
return browser_.get();
}
+ GtkWindow* window() { return window_; }
+
protected:
virtual void DestroyBrowser();
// Top level window.
@@ -292,6 +299,8 @@ class BrowserWindowGtk : public BrowserWindow,
#if defined(LINUX2)
// True if a drag is active. See description above setter for details.
bool drag_active_;
+ // Controls interactions with the window manager for popup panels.
+ PanelController* panel_controller_;
#endif
// A map which translates an X Window ID into its respective GtkWindow.
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index bb32927..7565815 100755
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -1584,7 +1584,7 @@ CustomDrawButton* TabStripGtk::MakeNewTabButton() {
#if defined(LINUX2)
CustomDrawButton* TabStripGtk::MakeTabOverviewButton() {
CustomDrawButton* button =
- new CustomDrawButton(IDR_TAB_OVERVIEW_BUTTON_ICON, 0, 0, 0);
+ new CustomDrawButton(IDR_TAB_OVERVIEW_BUTTON_ICON, 0, 0, 0, NULL);
g_signal_connect(G_OBJECT(button->widget()), "clicked",
G_CALLBACK(OnTabOverviewButtonClicked), this);
diff --git a/chrome/browser/views/panel_controller.cc b/chrome/browser/views/panel_controller.cc
new file mode 100644
index 0000000..c86aacd
--- /dev/null
+++ b/chrome/browser/views/panel_controller.cc
@@ -0,0 +1,237 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/views/panel_controller.h"
+
+#include <gdk/gdkx.h>
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+#include "app/resource_bundle.h"
+#include "base/logging.h"
+#include "base/singleton.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
+#include "chrome/browser/views/tabs/tab_overview_types.h"
+#include "chrome/common/x11_util.h"
+#include "grit/app_resources.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "views/controls/button/image_button.h"
+#include "views/controls/label.h"
+#include "views/event.h"
+#include "views/view.h"
+#include "views/widget/widget_gtk.h"
+
+static int close_button_width;
+static int close_button_height;
+static SkBitmap* close_button_n;
+static SkBitmap* close_button_h;
+static SkBitmap* close_button_p;
+static gfx::Font* title_font = NULL;
+
+namespace {
+
+const int kTitleWidth = 200;
+const int kTitleHeight = 24;
+const int kTitlePad = 8;
+const int kButtonPad = 8;
+
+static bool resources_initialized;
+static void InitializeResources() {
+ if (resources_initialized) {
+ return;
+ }
+
+ resources_initialized = true;
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ title_font = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont));
+ close_button_n = rb.GetBitmapNamed(IDR_TAB_CLOSE);
+ close_button_h = rb.GetBitmapNamed(IDR_TAB_CLOSE_H);
+ close_button_p = rb.GetBitmapNamed(IDR_TAB_CLOSE_P);
+ close_button_width = close_button_n->width();
+ close_button_height = close_button_n->height();
+}
+
+} // namespace
+
+PanelController::PanelController(BrowserWindowGtk* browser_window)
+ : browser_window_(browser_window),
+ panel_(browser_window->window()),
+ panel_xid_(x11_util::GetX11WindowFromGtkWidget(GTK_WIDGET(panel_))),
+ expanded_(true),
+ mouse_down_(false),
+ dragging_(false) {
+ title_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_WINDOW);
+ gfx::Rect title_bounds(
+ 0, 0, browser_window->GetNormalBounds().width(), kTitleHeight);
+ title_window_->Init(NULL, title_bounds);
+ title_ = title_window_->GetNativeView();
+ title_xid_ = x11_util::GetX11WindowFromGtkWidget(title_);
+
+ TabOverviewTypes* tab_overview = TabOverviewTypes::instance();
+ tab_overview->SetWindowType(
+ title_,
+ TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL_TITLEBAR,
+ NULL);
+ std::vector<int> type_params;
+ type_params.push_back(title_xid_);
+ type_params.push_back(expanded_ ? 1 : 0);
+ tab_overview->SetWindowType(
+ GTK_WIDGET(panel_),
+ TabOverviewTypes::WINDOW_TYPE_CHROME_PANEL,
+ &type_params);
+
+ g_signal_connect(
+ panel_, "client-event", G_CALLBACK(OnPanelClientEvent), this);
+
+ title_content_ = new TitleContentView(this);
+ title_window_->SetContentsView(title_content_);
+ title_window_->Show();
+}
+
+void PanelController::UpdateTitleBar() {
+ title_content_->title_label()->SetText(
+ browser_window_->browser()->GetCurrentPageTitle());
+}
+
+bool PanelController::TitleMousePressed(const views::MouseEvent& event) {
+ if (!event.IsOnlyLeftMouseButton()) {
+ return false;
+ }
+ gfx::Point abs_location = event.location();
+ views::View::ConvertPointToScreen(title_content_, &abs_location);
+ mouse_down_ = true;
+ mouse_down_abs_x_ = abs_location.x();
+ mouse_down_abs_y_ = abs_location.y();
+ mouse_down_offset_x_ = event.x();
+ mouse_down_offset_y_ = event.y();
+ dragging_ = false;
+ return true;
+}
+
+void PanelController::TitleMouseReleased(
+ const views::MouseEvent& event, bool canceled) {
+ if (!event.IsOnlyLeftMouseButton()) {
+ return;
+ }
+ // Only handle clicks that started in our window.
+ if (!mouse_down_) {
+ return;
+ }
+
+ mouse_down_ = false;
+ if (!dragging_) {
+ TabOverviewTypes::Message msg(
+ TabOverviewTypes::Message::WM_SET_PANEL_STATE);
+ msg.set_param(0, panel_xid_);
+ msg.set_param(1, expanded_ ? 0 : 1);
+ TabOverviewTypes::instance()->SendMessage(msg);
+ } else {
+ TabOverviewTypes::Message msg(
+ TabOverviewTypes::Message::WM_NOTIFY_PANEL_DRAG_COMPLETE);
+ msg.set_param(0, panel_xid_);
+ TabOverviewTypes::instance()->SendMessage(msg);
+ dragging_ = false;
+ }
+}
+
+bool PanelController::TitleMouseDragged(const views::MouseEvent& event) {
+ if (!mouse_down_) {
+ return false;
+ }
+
+ gfx::Point abs_location = event.location();
+ views::View::ConvertPointToScreen(title_content_, &abs_location);
+ if (!dragging_) {
+ if (views::View::ExceededDragThreshold(
+ abs_location.x() - mouse_down_abs_x_,
+ abs_location.y() - mouse_down_abs_y_)) {
+ dragging_ = true;
+ }
+ }
+ if (dragging_) {
+ TabOverviewTypes::Message msg(TabOverviewTypes::Message::WM_MOVE_PANEL);
+ msg.set_param(0, panel_xid_);
+ msg.set_param(1, abs_location.x() - mouse_down_offset_x_);
+ msg.set_param(2, abs_location.y() - mouse_down_offset_y_);
+ TabOverviewTypes::instance()->SendMessage(msg);
+ }
+ return true;
+}
+
+// static
+bool PanelController::OnPanelClientEvent(
+ GtkWidget* widget,
+ GdkEventClient* event,
+ PanelController* panel_controller) {
+ return panel_controller->PanelClientEvent(event);
+}
+
+bool PanelController::PanelClientEvent(GdkEventClient* event) {
+ TabOverviewTypes::Message msg;
+ TabOverviewTypes::instance()->DecodeMessage(*event, &msg);
+ if (msg.type() == TabOverviewTypes::Message::CHROME_NOTIFY_PANEL_STATE) {
+ expanded_ = msg.param(0);
+ }
+ return true;
+}
+
+void PanelController::Close() {
+ title_window_->Close();
+}
+
+void PanelController::ButtonPressed(views::Button* sender) {
+ if (sender == title_content_->close_button()) {
+ browser_window_->Close();
+ }
+}
+
+PanelController::TitleContentView::TitleContentView(
+ PanelController* panel_controller)
+ : panel_controller_(panel_controller) {
+ InitializeResources();
+ close_button_ = new views::ImageButton(panel_controller_);
+ close_button_->SetImage(views::CustomButton::BS_NORMAL, close_button_n);
+ close_button_->SetImage(views::CustomButton::BS_HOT, close_button_h);
+ close_button_->SetImage(views::CustomButton::BS_PUSHED, close_button_p);
+ AddChildView(close_button_);
+
+ title_label_ = new views::Label(std::wstring(), *title_font);
+ title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ AddChildView(title_label_);
+
+ set_background(views::Background::CreateSolidBackground(0xdd, 0xdd, 0xdd, 1));
+}
+
+void PanelController::TitleContentView::Layout() {
+ close_button_->SetBounds(
+ bounds().width() - (close_button_width + kButtonPad),
+ (bounds().height() - close_button_height) / 2,
+ close_button_width,
+ close_button_height);
+ title_label_->SetBounds(
+ kTitlePad,
+ 0,
+ bounds().width() - (kTitlePad + close_button_width + 2 * kButtonPad),
+ bounds().height());
+}
+
+bool PanelController::TitleContentView::OnMousePressed(
+ const views::MouseEvent& event) {
+ return panel_controller_->TitleMousePressed(event);
+}
+
+void PanelController::TitleContentView::OnMouseReleased(
+ const views::MouseEvent& event, bool canceled) {
+ return panel_controller_->TitleMouseReleased(event, canceled);
+}
+
+bool PanelController::TitleContentView::OnMouseDragged(
+ const views::MouseEvent& event) {
+ return panel_controller_->TitleMouseDragged(event);
+}
+
diff --git a/chrome/browser/views/panel_controller.h b/chrome/browser/views/panel_controller.h
new file mode 100644
index 0000000..3bb88a6
--- /dev/null
+++ b/chrome/browser/views/panel_controller.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_VIEWS_PANEL_CONTROLLER_H_
+#define CHROME_BROWSER_VIEWS_PANEL_CONTROLLER_H_
+
+#include <gtk/gtk.h>
+
+#include "views/controls/button/button.h"
+
+class BrowserWindowGtk;
+typedef unsigned long XID;
+
+namespace views {
+class ImageButton;
+class Label;
+class MouseEvent;
+class WidgetGtk;
+}
+
+// Controls interactions with the WM for popups / panels.
+class PanelController : public views::ButtonListener {
+ public:
+ explicit PanelController(BrowserWindowGtk* browser_window);
+ virtual ~PanelController() {}
+
+ bool TitleMousePressed(const views::MouseEvent& event);
+ void TitleMouseReleased(const views::MouseEvent& event, bool canceled);
+ bool TitleMouseDragged(const views::MouseEvent& event);
+ bool PanelClientEvent(GdkEventClient* event);
+
+ void UpdateTitleBar();
+ void Close();
+ // ButtonListener methods.
+ virtual void ButtonPressed(views::Button* sender);
+
+ private:
+ class TitleContentView : public views::View {
+ public:
+ explicit TitleContentView(PanelController* panelController);
+ virtual ~TitleContentView() {}
+ virtual void Layout();
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+ virtual bool OnMouseDragged(const views::MouseEvent& event);
+
+ views::Label* title_label() { return title_label_; }
+ views::ImageButton* close_button() { return close_button_; }
+
+ private:
+ views::Label* title_label_;
+ views::ImageButton* close_button_;
+ PanelController* panel_controller_;
+ DISALLOW_COPY_AND_ASSIGN(TitleContentView);
+ };
+
+ // Dispatches client events to PanelController instances
+ static bool OnPanelClientEvent(
+ GtkWidget* widget,
+ GdkEventClient* event,
+ PanelController* panel_controller);
+
+ // Browser window containing content.
+ BrowserWindowGtk* browser_window_;
+ // Gtk object for content.
+ GtkWindow* panel_;
+ // X id for content.
+ XID panel_xid_;
+
+ // Views object representing title.
+ views::WidgetGtk* title_window_;
+ // Gtk object representing title.
+ GtkWidget* title_;
+ // X id representing title.
+ XID title_xid_;
+
+ // Views object, holds title and close button.
+ TitleContentView* title_content_;
+
+ // Is the panel expanded or collapsed?
+ bool expanded_;
+
+ // Is the mouse button currently down?
+ bool mouse_down_;
+
+ // Cursor's absolute position when the mouse button was pressed.
+ int mouse_down_abs_x_;
+ int mouse_down_abs_y_;
+
+ // Cursor's offset from the upper-left corner of the titlebar when the
+ // mouse button was pressed.
+ int mouse_down_offset_x_;
+ int mouse_down_offset_y_;
+
+ // Is the titlebar currently being dragged? That is, has the cursor
+ // moved more than kDragThreshold away from its starting position?
+ bool dragging_;
+
+ DISALLOW_COPY_AND_ASSIGN(PanelController);
+};
+
+#endif // CHROME_BROWSER_PANEL_CONTROLLER_H_
+