Index: remoting/host/disconnect_window_gtk.cc |
diff --git a/remoting/host/disconnect_window_gtk.cc b/remoting/host/disconnect_window_gtk.cc |
index 3cdf58d7636cd0bf1994c10605f16f40f8aa6777..12837f154677b7b0fc17bc65078a4adbd0eb75d0 100644 |
--- a/remoting/host/disconnect_window_gtk.cc |
+++ b/remoting/host/disconnect_window_gtk.cc |
@@ -2,30 +2,42 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "remoting/host/disconnect_window.h" |
- |
#include <gtk/gtk.h> |
#include <math.h> |
+#include "base/bind.h" |
#include "base/compiler_specific.h" |
+#include "base/location.h" |
#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/single_thread_task_runner.h" |
#include "base/string_util.h" |
#include "base/utf_string_conversions.h" |
+#include "remoting/host/host_window.h" |
#include "remoting/host/ui_strings.h" |
#include "ui/base/gtk/gtk_signal.h" |
namespace remoting { |
-class DisconnectWindowGtk : public DisconnectWindow { |
+namespace { |
+ |
+class DisconnectWindowGtk : public HostWindow::Core { |
public: |
- explicit DisconnectWindowGtk(const UiStrings* ui_strings); |
+ DisconnectWindowGtk( |
+ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
+ const base::Closure& disconnect_callback, |
+ const std::string& username, |
+ const UiStrings& ui_strings); |
+ |
+ private: |
+ friend class base::RefCountedThreadSafe<Core>; |
virtual ~DisconnectWindowGtk(); |
- virtual bool Show(const base::Closure& disconnect_callback, |
- const std::string& username) OVERRIDE; |
- virtual void Hide() OVERRIDE; |
+ // HostWindow::Core overrides. |
+ virtual void StartOnUiThread() OVERRIDE; |
+ virtual void StopOnUiThread() OVERRIDE; |
- private: |
CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnDelete, GdkEvent*); |
CHROMEGTK_CALLBACK_0(DisconnectWindowGtk, void, OnClicked); |
CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnConfigure, |
@@ -33,9 +45,13 @@ class DisconnectWindowGtk : public DisconnectWindow { |
CHROMEGTK_CALLBACK_1(DisconnectWindowGtk, gboolean, OnButtonPress, |
GdkEventButton*); |
- void CreateWindow(); |
- |
+ // Invoked in the |caller_task_runner_| thread to disconnect the client |
+ // session. |
base::Closure disconnect_callback_; |
+ |
+ // Specifies the remote user name. |
+ std::string username_; |
+ |
GtkWidget* disconnect_window_; |
GtkWidget* message_; |
GtkWidget* button_; |
@@ -45,33 +61,51 @@ class DisconnectWindowGtk : public DisconnectWindow { |
int current_width_; |
int current_height_; |
- // Points to the localized strings. |
- const UiStrings* ui_strings_; |
- |
DISALLOW_COPY_AND_ASSIGN(DisconnectWindowGtk); |
}; |
-DisconnectWindowGtk::DisconnectWindowGtk(const UiStrings* ui_strings) |
- : disconnect_window_(NULL), |
+// Helper function for creating a rectangular path with rounded corners, as |
+// Cairo doesn't have this facility. |radius| is the arc-radius of each |
+// corner. The bounding rectangle extends from (0, 0) to (width, height). |
+void AddRoundRectPath(cairo_t* cairo_context, int width, int height, |
+ int radius) { |
+ cairo_new_sub_path(cairo_context); |
+ cairo_arc(cairo_context, width - radius, radius, radius, -M_PI_2, 0); |
+ cairo_arc(cairo_context, width - radius, height - radius, radius, 0, M_PI_2); |
+ cairo_arc(cairo_context, radius, height - radius, radius, M_PI_2, 2 * M_PI_2); |
+ cairo_arc(cairo_context, radius, radius, radius, 2 * M_PI_2, 3 * M_PI_2); |
+ cairo_close_path(cairo_context); |
+} |
+ |
+DisconnectWindowGtk::DisconnectWindowGtk( |
+ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
+ const base::Closure& disconnect_callback, |
+ const std::string& username, |
+ const UiStrings& ui_strings) |
+ : HostWindow::Core(caller_task_runner, |
+ ui_task_runner, |
+ ui_strings), |
+ disconnect_callback_(disconnect_callback), |
+ username_(username), |
+ disconnect_window_(NULL), |
current_width_(0), |
- current_height_(0), |
- ui_strings_(ui_strings) { |
+ current_height_(0) { |
} |
DisconnectWindowGtk::~DisconnectWindowGtk() { |
- Hide(); |
} |
-void DisconnectWindowGtk::CreateWindow() { |
- if (disconnect_window_) |
- return; |
+void DisconnectWindowGtk::StartOnUiThread() { |
+ DCHECK(ui_task_runner()->BelongsToCurrentThread()); |
+ DCHECK(!disconnect_window_); |
disconnect_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
GtkWindow* window = GTK_WINDOW(disconnect_window_); |
g_signal_connect(disconnect_window_, "delete-event", |
G_CALLBACK(OnDeleteThunk), this); |
- gtk_window_set_title(window, UTF16ToUTF8(ui_strings_->product_name).c_str()); |
+ gtk_window_set_title(window, UTF16ToUTF8(ui_strings().product_name).c_str()); |
gtk_window_set_resizable(window, FALSE); |
// Try to keep the window always visible. |
@@ -115,7 +149,7 @@ void DisconnectWindowGtk::CreateWindow() { |
gtk_container_add(GTK_CONTAINER(align), button_row); |
button_ = gtk_button_new_with_label( |
- UTF16ToUTF8(ui_strings_->disconnect_button_text).c_str()); |
+ UTF16ToUTF8(ui_strings().disconnect_button_text).c_str()); |
gtk_box_pack_end(GTK_BOX(button_row), button_, FALSE, FALSE, 0); |
g_signal_connect(button_, "clicked", G_CALLBACK(OnClickedThunk), this); |
@@ -131,63 +165,40 @@ void DisconnectWindowGtk::CreateWindow() { |
gtk_label_set_attributes(GTK_LABEL(message_), attributes); |
gtk_widget_show_all(disconnect_window_); |
-} |
- |
-bool DisconnectWindowGtk::Show(const base::Closure& disconnect_callback, |
- const std::string& username) { |
- DCHECK(disconnect_callback_.is_null()); |
- DCHECK(!disconnect_callback.is_null()); |
- DCHECK(!disconnect_window_); |
- |
- disconnect_callback_ = disconnect_callback; |
- CreateWindow(); |
string16 text = ReplaceStringPlaceholders( |
- ui_strings_->disconnect_message, UTF8ToUTF16(username), NULL); |
+ ui_strings().disconnect_message, UTF8ToUTF16(username_), NULL); |
gtk_label_set_text(GTK_LABEL(message_), UTF16ToUTF8(text).c_str()); |
- gtk_window_present(GTK_WINDOW(disconnect_window_)); |
- return true; |
+ gtk_window_present(window); |
} |
-void DisconnectWindowGtk::Hide() { |
+void DisconnectWindowGtk::StopOnUiThread() { |
+ DCHECK(ui_task_runner()->BelongsToCurrentThread()); |
+ |
if (disconnect_window_) { |
gtk_widget_destroy(disconnect_window_); |
disconnect_window_ = NULL; |
} |
- |
- disconnect_callback_.Reset(); |
} |
void DisconnectWindowGtk::OnClicked(GtkWidget* button) { |
- disconnect_callback_.Run(); |
- Hide(); |
+ DCHECK(ui_task_runner()->BelongsToCurrentThread()); |
+ |
+ caller_task_runner()->PostTask(FROM_HERE, disconnect_callback_); |
} |
-gboolean DisconnectWindowGtk::OnDelete(GtkWidget* window, GdkEvent* event) { |
- disconnect_callback_.Run(); |
- Hide(); |
+gboolean DisconnectWindowGtk::OnDelete(GtkWidget* window, |
+ GdkEvent* event) { |
+ DCHECK(ui_task_runner()->BelongsToCurrentThread()); |
+ caller_task_runner()->PostTask(FROM_HERE, disconnect_callback_); |
return TRUE; |
} |
-namespace { |
-// Helper function for creating a rectangular path with rounded corners, as |
-// Cairo doesn't have this facility. |radius| is the arc-radius of each |
-// corner. The bounding rectangle extends from (0, 0) to (width, height). |
-void AddRoundRectPath(cairo_t* cairo_context, int width, int height, |
- int radius) { |
- cairo_new_sub_path(cairo_context); |
- cairo_arc(cairo_context, width - radius, radius, radius, -M_PI_2, 0); |
- cairo_arc(cairo_context, width - radius, height - radius, radius, 0, M_PI_2); |
- cairo_arc(cairo_context, radius, height - radius, radius, M_PI_2, 2 * M_PI_2); |
- cairo_arc(cairo_context, radius, radius, radius, 2 * M_PI_2, 3 * M_PI_2); |
- cairo_close_path(cairo_context); |
-} |
- |
-} // namespace |
- |
gboolean DisconnectWindowGtk::OnConfigure(GtkWidget* widget, |
- GdkEventConfigure* event) { |
+ GdkEventConfigure* event) { |
+ DCHECK(ui_task_runner()->BelongsToCurrentThread()); |
+ |
// Only generate bitmaps if the size has actually changed. |
if (event->width == current_width_ && event->height == current_height_) |
return FALSE; |
@@ -273,7 +284,9 @@ gboolean DisconnectWindowGtk::OnConfigure(GtkWidget* widget, |
} |
gboolean DisconnectWindowGtk::OnButtonPress(GtkWidget* widget, |
- GdkEventButton* event) { |
+ GdkEventButton* event) { |
+ DCHECK(ui_task_runner()->BelongsToCurrentThread()); |
+ |
gtk_window_begin_move_drag(GTK_WINDOW(disconnect_window_), |
event->button, |
event->x_root, |
@@ -282,9 +295,20 @@ gboolean DisconnectWindowGtk::OnButtonPress(GtkWidget* widget, |
return FALSE; |
} |
-scoped_ptr<DisconnectWindow> DisconnectWindow::Create( |
- const UiStrings* ui_strings) { |
- return scoped_ptr<DisconnectWindow>(new DisconnectWindowGtk(ui_strings)); |
+} // namespace |
+ |
+scoped_ptr<HostWindow> HostWindow::CreateDisconnectWindow( |
+ scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, |
+ scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, |
+ const base::Closure& disconnect_callback, |
+ const std::string& username, |
+ const UiStrings& ui_strings) { |
+ scoped_refptr<Core> core = new DisconnectWindowGtk(caller_task_runner, |
+ ui_task_runner, |
+ disconnect_callback, |
+ username, |
+ ui_strings); |
+ return scoped_ptr<HostWindow>(new HostWindow(core)); |
} |
} // namespace remoting |