Super-simplistic status bubble on Linux.

(I just want to see when pages are loading, y'know...)

Review URL: http://codereview.chromium.org/21500

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10004 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 0fc5f3378..d91c114 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -42,6 +42,10 @@
 #include "net/url_request/url_request_context.h"
 #include "webkit/glue/window_open_disposition.h"
 
+#if defined(OS_WIN) || defined(OS_LINUX)
+#include "chrome/browser/status_bubble.h"
+#endif
+
 #if defined(OS_WIN)
 
 #include <windows.h>
@@ -60,7 +64,6 @@
 #include "chrome/browser/history_tab_ui.h"
 #include "chrome/browser/options_window.h"
 #include "chrome/browser/ssl/ssl_error_info.h"
-#include "chrome/browser/status_bubble.h"
 #include "chrome/browser/tab_contents/web_contents_view.h"
 #include "chrome/browser/task_manager.h"
 #include "chrome/browser/user_data_manager.h"
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index b17d35c..bc5860a 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -790,6 +790,7 @@
       'gtk/menu_gtk.cc',
       'gtk/nine_box.cc',
       'gtk/standard_menus.cc',
+      'gtk/status_bubble_gtk.cc',
       'process_singleton_linux.cc',
       'renderer_host/render_widget_host_view_gtk.cc',
       'tab_contents/web_contents_view_gtk.cc',
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 36e8e596..a1fa41ef 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -10,6 +10,7 @@
 #include "chrome/browser/browser.h"
 #include "chrome/browser/gtk/nine_box.h"
 #include "chrome/browser/gtk/browser_toolbar_view_gtk.h"
+#include "chrome/browser/gtk/status_bubble_gtk.h"
 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
 #include "chrome/browser/tab_contents/web_contents.h"
 
@@ -145,6 +146,8 @@
   // TODO(port): make this a pref.
   SetCustomFrame(false);
 
+  status_bubble_.reset(new StatusBubbleGtk(window_));
+
   gtk_container_add(GTK_CONTAINER(window_), vbox_);
 }
 
@@ -198,8 +201,7 @@
 }
 
 StatusBubble* BrowserWindowGtk::GetStatusBubble() {
-  NOTIMPLEMENTED();
-  return NULL;
+  return status_bubble_.get();
 }
 
 void BrowserWindowGtk::SelectedTabToolbarSizeChanged(bool is_animating) {
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index fc15e15..6ff3ce0 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -13,6 +13,7 @@
 
 class BrowserToolbarGtk;
 class NineBox;
+class StatusBubbleGtk;
 
 // An implementation of BrowserWindow for GTK.
 // Cross-platform code will interact with this object when
@@ -96,6 +97,9 @@
   bool custom_frame_;
 
   scoped_ptr<BrowserToolbarGtk> toolbar_;
+
+  // The status bubble manager.  Always non-NULL.
+  scoped_ptr<StatusBubbleGtk> status_bubble_;
 };
 
 #endif  // CHROME_BROWSER_WINDOW_GTK_H_
diff --git a/chrome/browser/gtk/status_bubble_gtk.cc b/chrome/browser/gtk/status_bubble_gtk.cc
new file mode 100644
index 0000000..4e67bee5
--- /dev/null
+++ b/chrome/browser/gtk/status_bubble_gtk.cc
@@ -0,0 +1,73 @@
+// 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/gtk/status_bubble_gtk.h"
+
+#include "base/string_util.h"
+#include "googleurl/src/gurl.h"
+
+StatusBubbleGtk::StatusBubbleGtk(GtkWindow* parent)
+    : parent_(parent), window_(NULL) {
+}
+
+StatusBubbleGtk::~StatusBubbleGtk() {
+  Hide();
+}
+
+void StatusBubbleGtk::SetStatus(const std::string& status) {
+  if (status.empty()) {
+    Hide();
+    return;
+  }
+
+  if (!window_)
+    Create();
+
+  gtk_label_set_text(GTK_LABEL(label_), status.c_str());
+  Reposition();
+  gtk_widget_show(window_);
+}
+
+void StatusBubbleGtk::SetStatus(const std::wstring& status) {
+  SetStatus(WideToUTF8(status));
+}
+
+void StatusBubbleGtk::SetURL(const GURL& url, const std::wstring& languages) {
+  SetStatus(url.spec());
+}
+
+void StatusBubbleGtk::Hide() {
+  if (!window_)
+    return;
+  gtk_widget_destroy(window_);
+  window_ = NULL;
+}
+
+void StatusBubbleGtk::MouseMoved() {
+  if (!window_)
+    return;
+  // We ignore for now.
+  // TODO(port): the fancy sliding behavior.
+}
+
+void StatusBubbleGtk::Create() {
+  if (window_)
+    return;
+
+  window_ = gtk_window_new(GTK_WINDOW_POPUP);
+  gtk_window_set_transient_for(GTK_WINDOW(window_), parent_);
+  gtk_container_set_border_width(GTK_CONTAINER(window_), 2);
+  label_ = gtk_label_new("");
+  gtk_widget_show(label_);
+  gtk_container_add(GTK_CONTAINER(window_), label_);
+}
+
+void StatusBubbleGtk::Reposition() {
+  int x, y, width, height, parent_height;
+  gtk_window_get_position(parent_, &x, &y);
+  gtk_window_get_size(parent_, &width, &parent_height);
+  gtk_window_get_size(GTK_WINDOW(window_), &width, &height);
+  // TODO(port): RTL positioning.
+  gtk_window_move(GTK_WINDOW(window_), x, y + parent_height - height);
+}
diff --git a/chrome/browser/gtk/status_bubble_gtk.h b/chrome/browser/gtk/status_bubble_gtk.h
new file mode 100644
index 0000000..81358112
--- /dev/null
+++ b/chrome/browser/gtk/status_bubble_gtk.h
@@ -0,0 +1,47 @@
+// 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_STATUS_BUBBLE_GTK_H_
+#define CHROME_BROWSER_STATUS_BUBBLE_GTK_H_
+
+#include <string>
+
+#include <gtk/gtk.h>
+
+#include "chrome/browser/status_bubble.h"
+
+class GURL;
+
+class StatusBubbleGtk : public StatusBubble {
+ public:
+  StatusBubbleGtk(GtkWindow* parent);
+  virtual ~StatusBubbleGtk();
+
+  // StatusBubble implementation.
+  virtual void SetStatus(const std::wstring& status);
+  virtual void SetURL(const GURL& url, const std::wstring& languages);
+  virtual void Hide();
+  virtual void MouseMoved();
+
+  void SetStatus(const std::string& status_utf8);
+
+ private:
+  // Construct the window/widget.
+  void Create();
+
+  // Reposition ourselves atop our parent window.
+  void Reposition();
+
+  // The window we display on top of.
+  GtkWindow* parent_;
+
+  // The top-level (popup) window we own.
+  // NULL when we're not showing.
+  GtkWidget* window_;
+
+  // The GtkLabel holding the text.
+  GtkWidget* label_;
+};
+
+#endif  // #ifndef CHROME_BROWSER_STATUS_BUBBLE_GTK_H_
diff --git a/chrome/browser/status_bubble.h b/chrome/browser/status_bubble.h
index 04b6369..30aa6db 100644
--- a/chrome/browser/status_bubble.h
+++ b/chrome/browser/status_bubble.h
@@ -39,4 +39,4 @@
   virtual void MouseMoved() = 0;
 };
 
-#endif  // #ifndef CHROME_BROWSER_STATUS_BUBBLE_H_
\ No newline at end of file
+#endif  // #ifndef CHROME_BROWSER_STATUS_BUBBLE_H_
diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc
index c1c0fd9..575714e 100644
--- a/chrome/browser/tab_contents/web_contents.cc
+++ b/chrome/browser/tab_contents/web_contents.cc
@@ -357,11 +357,8 @@
     case net::LOAD_STATE_SENDING_REQUEST:
       return l10n_util::GetString(IDS_LOAD_STATE_SENDING_REQUEST);
     case net::LOAD_STATE_WAITING_FOR_RESPONSE:
-#if defined(OS_WIN)
-      // TODO(port): GetStringF() is currently disabled for non-win platforms.
       return l10n_util::GetStringF(IDS_LOAD_STATE_WAITING_FOR_RESPONSE,
                                    load_state_host_);
-#endif
     // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE
     case net::LOAD_STATE_IDLE:
     case net::LOAD_STATE_READING_RESPONSE: