1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/shell/shell.h"
7 #include <gdk/gdkkeysyms.h>
10 #include "base/logging.h"
11 #include "base/string_piece.h"
12 #include "base/utf_string_conversions.h"
13 #include "content/public/browser/browser_context.h"
14 #include "content/public/browser/native_web_keyboard_event.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/browser/web_contents_view.h"
17 #include "content/public/common/renderer_preferences.h"
18 #include "content/shell/shell_browser_context.h"
19 #include "content/shell/shell_content_browser_client.h"
25 // Callback for Debug > Show web inspector... menu item.
26 gboolean
ShowWebInspectorActivated(GtkWidget
* widget
, Shell
* shell
) {
27 shell
->ShowDevTools();
28 return FALSE
; // Don't stop this message.
31 GtkWidget
* AddMenuEntry(GtkWidget
* menu_widget
, const char* text
,
32 GCallback callback
, Shell
* shell
) {
33 GtkWidget
* entry
= gtk_menu_item_new_with_label(text
);
34 g_signal_connect(entry
, "activate", callback
, shell
);
35 gtk_menu_shell_append(GTK_MENU_SHELL(menu_widget
), entry
);
39 GtkWidget
* CreateMenu(GtkWidget
* menu_bar
, const char* text
) {
40 GtkWidget
* menu_widget
= gtk_menu_new();
41 GtkWidget
* menu_header
= gtk_menu_item_new_with_label(text
);
42 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_header
), menu_widget
);
43 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar
), menu_header
);
47 GtkWidget
* CreateMenuBar(Shell
* shell
) {
48 GtkWidget
* menu_bar
= gtk_menu_bar_new();
49 GtkWidget
* debug_menu
= CreateMenu(menu_bar
, "Debug");
50 AddMenuEntry(debug_menu
, "Show web inspector...",
51 G_CALLBACK(ShowWebInspectorActivated
), shell
);
57 void Shell::PlatformInitialize() {
60 void Shell::PlatformCleanUp() {
61 // Nothing to clean up; GTK will clean up the widgets shortly after.
64 void Shell::PlatformEnableUIControl(UIControl control
, bool is_enabled
) {
68 GtkToolItem
* item
= NULL
;
74 item
= forward_button_
;
80 NOTREACHED() << "Unknown UI control";
83 gtk_widget_set_sensitive(GTK_WIDGET(item
), is_enabled
);
86 void Shell::PlatformSetAddressBarURL(const GURL
& url
) {
90 gtk_entry_set_text(GTK_ENTRY(url_edit_view_
), url
.spec().c_str());
93 void Shell::PlatformSetIsLoading(bool loading
) {
98 gtk_spinner_start(GTK_SPINNER(spinner_
));
100 gtk_spinner_stop(GTK_SPINNER(spinner_
));
103 void Shell::PlatformCreateWindow(int width
, int height
) {
107 window_
= GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL
));
108 gtk_window_set_title(window_
, "Content Shell");
109 g_signal_connect(G_OBJECT(window_
), "destroy",
110 G_CALLBACK(OnWindowDestroyedThunk
), this);
112 vbox_
= gtk_vbox_new(FALSE
, 0);
114 // Create the menu bar.
115 GtkWidget
* menu_bar
= CreateMenuBar(this);
116 gtk_box_pack_start(GTK_BOX(vbox_
), menu_bar
, FALSE
, FALSE
, 0);
118 // Create the object that mediates accelerators.
119 GtkAccelGroup
* accel_group
= gtk_accel_group_new();
120 gtk_window_add_accel_group(GTK_WINDOW(window_
), accel_group
);
122 // Set global window handling accelerators:
123 gtk_accel_group_connect(
124 accel_group
, GDK_w
, GDK_CONTROL_MASK
,
126 g_cclosure_new(G_CALLBACK(OnCloseWindowKeyPressedThunk
),
129 gtk_accel_group_connect(
130 accel_group
, GDK_n
, GDK_CONTROL_MASK
,
132 g_cclosure_new(G_CALLBACK(OnNewWindowKeyPressedThunk
),
135 GtkWidget
* toolbar
= gtk_toolbar_new();
136 // Turn off the labels on the toolbar buttons.
137 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar
), GTK_TOOLBAR_ICONS
);
139 back_button_
= gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK
);
140 g_signal_connect(back_button_
, "clicked",
141 G_CALLBACK(&OnBackButtonClickedThunk
), this);
142 gtk_toolbar_insert(GTK_TOOLBAR(toolbar
), back_button_
, -1 /* append */);
143 gtk_widget_add_accelerator(GTK_WIDGET(back_button_
), "clicked", accel_group
,
144 GDK_Left
, GDK_MOD1_MASK
, GTK_ACCEL_VISIBLE
);
146 forward_button_
= gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD
);
147 g_signal_connect(forward_button_
, "clicked",
148 G_CALLBACK(&OnForwardButtonClickedThunk
), this);
149 gtk_toolbar_insert(GTK_TOOLBAR(toolbar
), forward_button_
, -1 /* append */);
150 gtk_widget_add_accelerator(GTK_WIDGET(forward_button_
), "clicked",
152 GDK_Right
, GDK_MOD1_MASK
, GTK_ACCEL_VISIBLE
);
154 reload_button_
= gtk_tool_button_new_from_stock(GTK_STOCK_REFRESH
);
155 g_signal_connect(reload_button_
, "clicked",
156 G_CALLBACK(&OnReloadButtonClickedThunk
), this);
157 gtk_toolbar_insert(GTK_TOOLBAR(toolbar
), reload_button_
, -1 /* append */);
158 gtk_widget_add_accelerator(GTK_WIDGET(reload_button_
), "clicked",
160 GDK_r
, GDK_CONTROL_MASK
, GTK_ACCEL_VISIBLE
);
162 stop_button_
= gtk_tool_button_new_from_stock(GTK_STOCK_STOP
);
163 g_signal_connect(stop_button_
, "clicked",
164 G_CALLBACK(&OnStopButtonClickedThunk
), this);
165 gtk_toolbar_insert(GTK_TOOLBAR(toolbar
), stop_button_
, -1 /* append */);
167 url_edit_view_
= gtk_entry_new();
168 g_signal_connect(G_OBJECT(url_edit_view_
), "activate",
169 G_CALLBACK(&OnURLEntryActivateThunk
), this);
171 gtk_accel_group_connect(
172 accel_group
, GDK_l
, GDK_CONTROL_MASK
,
174 g_cclosure_new(G_CALLBACK(OnHighlightURLViewThunk
),
177 GtkToolItem
* tool_item
= gtk_tool_item_new();
178 gtk_container_add(GTK_CONTAINER(tool_item
), url_edit_view_
);
179 gtk_tool_item_set_expand(tool_item
, TRUE
);
180 gtk_toolbar_insert(GTK_TOOLBAR(toolbar
), tool_item
, -1 /* append */);
182 // Center a 20x20 spinner in a 26x24 area.
183 GtkWidget
* spinner_alignment
= gtk_alignment_new(0.5, 0.5, 0, 0);
184 gtk_alignment_set_padding(GTK_ALIGNMENT(spinner_alignment
), 2, 2, 4, 4);
185 spinner_
= gtk_spinner_new();
186 gtk_widget_set_size_request(spinner_
, 20, 20);
187 gtk_container_add(GTK_CONTAINER(spinner_alignment
), spinner_
);
189 spinner_item_
= gtk_tool_item_new();
190 gtk_container_add(GTK_CONTAINER(spinner_item_
), spinner_alignment
);
191 gtk_toolbar_insert(GTK_TOOLBAR(toolbar
), spinner_item_
, -1 /* append */);
193 gtk_box_pack_start(GTK_BOX(vbox_
), toolbar
, FALSE
, FALSE
, 0);
195 gtk_container_add(GTK_CONTAINER(window_
), vbox_
);
196 gtk_widget_show_all(GTK_WIDGET(window_
));
198 SizeTo(width
, height
);
201 void Shell::PlatformSetContents() {
205 WebContentsView
* content_view
= web_contents_
->GetView();
206 gtk_container_add(GTK_CONTAINER(vbox_
), content_view
->GetNativeView());
209 void Shell::SizeTo(int width
, int height
) {
210 content_width_
= width
;
211 content_height_
= height
;
212 if (web_contents_
.get())
213 gtk_widget_set_size_request(web_contents_
->GetNativeView(), width
, height
);
216 void Shell::PlatformResizeSubViews() {
217 SizeTo(content_width_
, content_height_
);
220 void Shell::Close() {
224 gtk_widget_destroy(GTK_WIDGET(window_
));
227 void Shell::OnBackButtonClicked(GtkWidget
* widget
) {
231 void Shell::OnForwardButtonClicked(GtkWidget
* widget
) {
235 void Shell::OnReloadButtonClicked(GtkWidget
* widget
) {
239 void Shell::OnStopButtonClicked(GtkWidget
* widget
) {
243 void Shell::OnURLEntryActivate(GtkWidget
* entry
) {
244 const gchar
* str
= gtk_entry_get_text(GTK_ENTRY(entry
));
246 if (!url
.has_scheme())
247 url
= GURL(std::string("http://") + std::string(str
));
251 // Callback for when the main window is destroyed.
252 gboolean
Shell::OnWindowDestroyed(GtkWidget
* window
) {
254 return FALSE
; // Don't stop this message.
257 gboolean
Shell::OnCloseWindowKeyPressed(GtkAccelGroup
* accel_group
,
258 GObject
* acceleratable
,
260 GdkModifierType modifier
) {
261 gtk_widget_destroy(GTK_WIDGET(window_
));
265 gboolean
Shell::OnNewWindowKeyPressed(GtkAccelGroup
* accel_group
,
266 GObject
* acceleratable
,
268 GdkModifierType modifier
) {
269 ShellBrowserContext
* browser_context
=
270 static_cast<ShellContentBrowserClient
*>(
271 GetContentClient()->browser())->browser_context();
272 Shell::CreateNewWindow(browser_context
,
280 gboolean
Shell::OnHighlightURLView(GtkAccelGroup
* accel_group
,
281 GObject
* acceleratable
,
283 GdkModifierType modifier
) {
284 gtk_widget_grab_focus(GTK_WIDGET(url_edit_view_
));
288 void Shell::PlatformSetTitle(const string16
& title
) {
292 std::string title_utf8
= UTF16ToUTF8(title
);
293 gtk_window_set_title(GTK_WINDOW(window_
), title_utf8
.c_str());
296 } // namespace content