~ps-jenkins/unity-chromium-extension/latestsnapshot-2.4.8+13.10.20140327-0ubuntu1

« back to all changes in this revision

Viewing changes to chromium-patches/stable-28.0.1500.45/4-chromeless-window-launch-option.patch

  • Committer: Alexandre Abreu
  • Date: 2013-06-28 18:38:57 UTC
  • Revision ID: alexandre.abreu@canonical.com-20130628183857-jqodta6fs33xu4ql
Support chromium 28

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Index: src/chrome/browser/extensions/api/module/module.cc
 
2
===================================================================
 
3
--- src/chrome/browser/extensions/api/module/module.cc  (revision 205727)
 
4
+++ src/chrome/browser/extensions/api/module/module.cc  (working copy)
 
5
@@ -7,9 +7,28 @@
 
6
 #include <string>
 
7
 
 
8
 #include "chrome/browser/extensions/extension_prefs.h"
 
9
+#include "chrome/browser/extensions/extension_tab_util.h"
 
10
 #include "chrome/browser/extensions/extension_service.h"
 
11
+#include "chrome/browser/ui/browser.h"
 
12
 #include "chrome/browser/profiles/profile.h"
 
13
+#include "chrome/common/chrome_switches.h"
 
14
 
 
15
+#if defined(OS_LINUX) && defined(TOOLKIT_GTK)
 
16
+#include <gdk/gdk.h>
 
17
+#include <gdk/gdkx.h>
 
18
+#endif
 
19
+
 
20
+#if defined(OS_LINUX) && defined(TOOLKIT_GTK)
 
21
+
 
22
+namespace {
 
23
+
 
24
+const char kNoCurrentWindowError[] = "No current window";
 
25
+const char kCouldNotIdentifyTab[] = "Could not find tab with specified ID";
 
26
+
 
27
+} // namespace {
 
28
+
 
29
+#endif
 
30
+
 
31
 namespace extensions {
 
32
 
 
33
 ExtensionPrefs* ExtensionSetUpdateUrlDataFunction::extension_prefs() {
 
34
@@ -42,4 +61,36 @@
 
35
   return true;
 
36
 }
 
37
 
 
38
+bool ExtensionIsChromelessWindowFunction::RunImpl() {
 
39
+  bool is_chromeless = false;
 
40
+
 
41
+  int tab_id = -1;
 
42
+  if (!args_->GetInteger(0, &tab_id)) {
 
43
+    Browser* browser = GetCurrentBrowser();
 
44
+    if (!browser) {
 
45
+      error_ = kNoCurrentWindowError;
 
46
+      return false;
 
47
+    }
 
48
+    is_chromeless = browser->is_chromeless_mode();
 
49
+  }
 
50
+  else {
 
51
+    Browser* browser = NULL;
 
52
+    if (!ExtensionTabUtil::GetTabById(tab_id,
 
53
+                                      profile(),
 
54
+                                      NULL,
 
55
+                                      &browser,
 
56
+                                      NULL,
 
57
+                                      NULL,
 
58
+                                      NULL)) {
 
59
+      error_ = kCouldNotIdentifyTab;
 
60
+      return false;
 
61
+    }
 
62
+    is_chromeless = browser->is_chromeless_mode();
 
63
+  }
 
64
+
 
65
+  SetResult(Value::CreateBooleanValue(is_chromeless));
 
66
+
 
67
+  return true;
 
68
+}
 
69
+
 
70
 }  // namespace extensions
 
71
Index: src/chrome/browser/extensions/api/module/module.h
 
72
===================================================================
 
73
--- src/chrome/browser/extensions/api/module/module.h   (revision 205727)
 
74
+++ src/chrome/browser/extensions/api/module/module.h   (working copy)
 
75
@@ -51,6 +51,18 @@
 
76
   virtual bool RunImpl() OVERRIDE;
 
77
 };
 
78
 
 
79
+class ExtensionIsChromelessWindowFunction : public SyncExtensionFunction {
 
80
+ public:
 
81
+  DECLARE_EXTENSION_FUNCTION("extension.isChromelessWindow",
 
82
+                             EXTENSION_IS_CHROMELESS_WINDOW);
 
83
+
 
84
+ protected:
 
85
+  virtual ~ExtensionIsChromelessWindowFunction() {}
 
86
+
 
87
+  // ExtensionFunction:
 
88
+  virtual bool RunImpl() OVERRIDE;
 
89
+};
 
90
+
 
91
 }  // namespace extensions
 
92
 
 
93
 #endif  // CHROME_BROWSER_EXTENSIONS_API_MODULE_MODULE_H__
 
94
Index: src/chrome/browser/extensions/extension_function_histogram_value.h
 
95
===================================================================
 
96
--- src/chrome/browser/extensions/extension_function_histogram_value.h  (revision 205727)
 
97
+++ src/chrome/browser/extensions/extension_function_histogram_value.h  (working copy)
 
98
@@ -391,6 +391,7 @@
 
99
   SYSTEMINDICATOR_DISABLE,
 
100
   SCRIPTBADGE_SETPOPUP,
 
101
   EXTENSION_ISALLOWEDFILESCHEMEACCESS,
 
102
+  EXTENSION_IS_CHROMELESS_WINDOW,
 
103
   EXPERIMENTAL_IDENTITY_LAUNCHWEBAUTHFLOW,
 
104
   FILEBROWSERPRIVATE_GETDRIVECONNECTIONSTATE,
 
105
   TABS_DETECTLANGUAGE,
 
106
Index: src/chrome/browser/sessions/session_service.cc
 
107
===================================================================
 
108
--- src/chrome/browser/sessions/session_service.cc      (revision 205727)
 
109
+++ src/chrome/browser/sessions/session_service.cc      (working copy)
 
110
@@ -1555,7 +1555,8 @@
 
111
 bool SessionService::ShouldTrackBrowser(Browser* browser) const {
 
112
   AppType app_type = browser->is_app() ? TYPE_APP : TYPE_NORMAL;
 
113
   return browser->profile() == profile() &&
 
114
-         should_track_changes_for_browser_type(browser->type(), app_type);
 
115
+         should_track_changes_for_browser_type(browser->type(), app_type) &&
 
116
+         !browser->is_chromeless_mode();
 
117
 }
 
118
 
 
119
 bool SessionService::should_track_changes_for_browser_type(Browser::Type type,
 
120
Index: src/chrome/browser/ui/browser.cc
 
121
===================================================================
 
122
--- src/chrome/browser/ui/browser.cc    (revision 205727)
 
123
+++ src/chrome/browser/ui/browser.cc    (working copy)
 
124
@@ -254,6 +254,7 @@
 
125
       profile(profile),
 
126
       host_desktop_type(host_desktop_type),
 
127
       app_type(APP_TYPE_HOST),
 
128
+      is_chromeless_mode(false),
 
129
       initial_show_state(ui::SHOW_STATE_DEFAULT),
 
130
       is_session_restore(false),
 
131
       window(NULL) {
 
132
@@ -266,12 +267,23 @@
 
133
       profile(profile),
 
134
       host_desktop_type(host_desktop_type),
 
135
       app_type(APP_TYPE_HOST),
 
136
+      is_chromeless_mode(false),
 
137
       initial_show_state(ui::SHOW_STATE_DEFAULT),
 
138
       is_session_restore(false),
 
139
       window(NULL) {
 
140
 }
 
141
 
 
142
 // static
 
143
+Browser::CreateParams Browser::CreateParams::CreateChromeless(
 
144
+    Profile * profile,
 
145
+    chrome::HostDesktopType host_desktop_type)
 
146
+{
 
147
+  CreateParams params(profile, host_desktop_type);
 
148
+  params.is_chromeless_mode = true;
 
149
+  return params;
 
150
+}
 
151
+
 
152
+// static
 
153
 Browser::CreateParams Browser::CreateParams::CreateForApp(
 
154
     Type type,
 
155
     const std::string& app_name,
 
156
@@ -340,6 +352,7 @@
 
157
       cancel_download_confirmation_state_(NOT_PROMPTED),
 
158
       override_bounds_(params.initial_bounds),
 
159
       initial_show_state_(params.initial_show_state),
 
160
+      is_chromeless_mode_(params.is_chromeless_mode),
 
161
       is_session_restore_(params.is_session_restore),
 
162
       host_desktop_type_(params.host_desktop_type),
 
163
       unload_controller_(new chrome::UnloadController(this)),
 
164
@@ -518,6 +531,10 @@
 
165
   return find_bar_controller_.get() != NULL;
 
166
 }
 
167
 
 
168
+bool Browser::is_chromeless_mode () const {
 
169
+  return is_chromeless_mode_;
 
170
+}
 
171
+
 
172
 bool Browser::is_app() const {
 
173
   return !app_name_.empty();
 
174
 }
 
175
@@ -563,7 +580,7 @@
 
176
     return title;
 
177
 #endif
 
178
   // Don't append the app name to window titles on app frames and app popups
 
179
-  return is_app() ?
 
180
+  return (is_app() || is_chromeless_mode()) ?
 
181
       title :
 
182
       l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, title);
 
183
 }
 
184
@@ -621,7 +638,8 @@
 
185
     tab_restore_service->BrowserClosing(tab_restore_service_delegate());
 
186
 #endif
 
187
 
 
188
-  if (tab_restore_service && is_type_tabbed() && tab_strip_model_->count())
 
189
+  if (tab_restore_service && is_type_tabbed() &&
 
190
+          tab_strip_model_->count() && !is_chromeless_mode())
 
191
     tab_restore_service->BrowserClosing(tab_restore_service_delegate());
 
192
 
 
193
   // TODO(sky): convert session/tab restore to use notification.
 
194
@@ -2104,20 +2122,20 @@
 
195
 
 
196
   unsigned int features = FEATURE_INFOBAR | FEATURE_DOWNLOADSHELF;
 
197
 
 
198
-  if (is_type_tabbed())
 
199
+  if (is_type_tabbed() && !is_chromeless_mode())
 
200
     features |= FEATURE_BOOKMARKBAR;
 
201
 
 
202
   if (!hide_ui_for_fullscreen) {
 
203
-    if (!is_type_tabbed())
 
204
+    if (is_type_tabbed() && !is_chromeless_mode())
 
205
       features |= FEATURE_TITLEBAR;
 
206
 
 
207
     if (is_type_tabbed())
 
208
       features |= FEATURE_TABSTRIP;
 
209
 
 
210
-    if (is_type_tabbed())
 
211
+    if (is_type_tabbed() && !is_chromeless_mode())
 
212
       features |= FEATURE_TOOLBAR;
 
213
 
 
214
-    if (!is_app())
 
215
+    if (!is_app() && !is_chromeless_mode())
 
216
       features |= FEATURE_LOCATIONBAR;
 
217
   }
 
218
   return !!(features & feature);
 
219
Index: src/chrome/browser/ui/browser.h
 
220
===================================================================
 
221
--- src/chrome/browser/ui/browser.h     (revision 205727)
 
222
+++ src/chrome/browser/ui/browser.h     (working copy)
 
223
@@ -164,6 +164,10 @@
 
224
         Profile* profile,
 
225
         chrome::HostDesktopType host_desktop_type);
 
226
 
 
227
+    // Like Create, but creates a chromeless browser.
 
228
+    static CreateParams CreateChromeless(Profile * profile,
 
229
+                                        chrome::HostDesktopType host_desktop_type);
 
230
+
 
231
     // The browser type.
 
232
     Type type;
 
233
 
 
234
@@ -182,6 +186,9 @@
 
235
     // Type of app (host or child). See description of AppType.
 
236
     AppType app_type;
 
237
 
 
238
+    // If the browser instance is supposed to be a chromeless one.
 
239
+    bool is_chromeless_mode;
 
240
+
 
241
     // The bounds of the window to open.
 
242
     gfx::Rect initial_bounds;
 
243
 
 
244
@@ -437,6 +444,7 @@
 
245
   bool is_type_tabbed() const { return type_ == TYPE_TABBED; }
 
246
   bool is_type_popup() const { return type_ == TYPE_POPUP; }
 
247
 
 
248
+  bool is_chromeless_mode() const;
 
249
   bool is_app() const;
 
250
   bool is_devtools() const;
 
251
 
 
252
@@ -811,6 +819,8 @@
 
253
   // 2) we launch an undocked devtool window.
 
254
   std::string app_name_;
 
255
 
 
256
+  bool is_chromeless_mode_;
 
257
+
 
258
   // Type of app (host or child). See description of AppType.
 
259
   AppType app_type_;
 
260
 
 
261
Index: src/chrome/browser/ui/browser_command_controller.cc
 
262
===================================================================
 
263
--- src/chrome/browser/ui/browser_command_controller.cc (revision 205727)
 
264
+++ src/chrome/browser/ui/browser_command_controller.cc (working copy)
 
265
@@ -4,6 +4,7 @@
 
266
 
 
267
 #include "chrome/browser/ui/browser_command_controller.h"
 
268
 
 
269
+#include "base/command_line.h"
 
270
 #include "base/prefs/pref_service.h"
 
271
 #include "chrome/app/chrome_command_ids.h"
 
272
 #include "chrome/browser/browser_process.h"
 
273
@@ -27,6 +28,7 @@
 
274
 #include "chrome/browser/ui/tabs/tab_strip_model_utils.h"
 
275
 #include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h"
 
276
 #include "chrome/common/chrome_notification_types.h"
 
277
+#include "chrome/common/chrome_switches.h"
 
278
 #include "chrome/common/pref_names.h"
 
279
 #include "chrome/common/profiling.h"
 
280
 #include "content/public/browser/native_web_keyboard_event.h"
 
281
@@ -814,7 +816,8 @@
 
282
 
 
283
 bool BrowserCommandController::IsShowingMainUI() {
 
284
   bool should_hide_ui = window() && window()->ShouldHideUIForFullscreen();
 
285
-  return browser_->is_type_tabbed() && !should_hide_ui;
 
286
+  return browser_->is_type_tabbed() && !should_hide_ui &&
 
287
+    !browser_->is_chromeless_mode();
 
288
 }
 
289
 
 
290
 void BrowserCommandController::InitCommandState() {
 
291
@@ -822,6 +825,9 @@
 
292
   // (like Back & Forward with initial page load) must have their state
 
293
   // initialized here, otherwise they will be forever disabled.
 
294
 
 
295
+  bool started_in_chromeless =
 
296
+    CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeless);
 
297
+
 
298
   // Navigation commands
 
299
   command_updater_.UpdateCommandEnabled(IDC_RELOAD, true);
 
300
   command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true);
 
301
@@ -829,9 +835,10 @@
 
302
 
 
303
   // Window management commands
 
304
   command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true);
 
305
-  command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true);
 
306
+  command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, !started_in_chromeless);
 
307
   command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true);
 
308
-  command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true);
 
309
+  command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
 
310
+                                        !started_in_chromeless);
 
311
   command_updater_.UpdateCommandEnabled(IDC_RESTORE_TAB, false);
 
312
 #if defined(OS_WIN) && defined(USE_ASH)
 
313
   if (browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
 
314
@@ -894,20 +901,23 @@
 
315
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
 
316
 
 
317
   // Show various bits of UI
 
318
-  UpdateOpenFileState(&command_updater_);
 
319
+  UpdateOpenFileState(&command_updater_, started_in_chromeless);
 
320
   command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false);
 
321
   UpdateCommandsForDevTools();
 
322
   command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager());
 
323
   command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY,
 
324
-                                        !profile()->IsGuestSession());
 
325
+                                        !profile()->IsGuestSession() &&
 
326
+                                            !started_in_chromeless);
 
327
   command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true);
 
328
   command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true);
 
329
   command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true);
 
330
   command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU,
 
331
-                                        !profile()->IsGuestSession());
 
332
+                                        !profile()->IsGuestSession() &&
 
333
+                                            !started_in_chromeless);
 
334
   command_updater_.UpdateCommandEnabled(IDC_RECENT_TABS_MENU,
 
335
                                         !profile()->IsGuestSession() &&
 
336
-                                        !profile()->IsOffTheRecord());
 
337
+                                        !profile()->IsOffTheRecord() &&
 
338
+                                        !started_in_chromeless);
 
339
 
 
340
   UpdateShowSyncState(true);
 
341
 
 
342
@@ -915,7 +925,9 @@
 
343
   bool normal_window = browser_->is_type_tabbed();
 
344
 
 
345
   // Navigation commands
 
346
-  command_updater_.UpdateCommandEnabled(IDC_HOME, normal_window);
 
347
+  command_updater_.UpdateCommandEnabled(IDC_HOME,
 
348
+                                        normal_window &&
 
349
+                                        !started_in_chromeless);
 
350
 
 
351
   // Window management commands
 
352
   command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window);
 
353
@@ -943,7 +955,9 @@
 
354
   command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window);
 
355
 
 
356
   // Show various bits of UI
 
357
-  command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window);
 
358
+  command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA,
 
359
+                                        normal_window &&
 
360
+                                            !started_in_chromeless);
 
361
 
 
362
   // The upgrade entry and the view incompatibility entry should always be
 
363
   // enabled. Whether they are visible is a separate matter determined on menu
 
364
@@ -953,7 +967,8 @@
 
365
 
 
366
   // View Background Pages entry is always enabled, but is hidden if there are
 
367
   // no background pages.
 
368
-  command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES, true);
 
369
+  command_updater_.UpdateCommandEnabled(IDC_VIEW_BACKGROUND_PAGES,
 
370
+                                        !started_in_chromeless);
 
371
 
 
372
   // Toggle speech input
 
373
   command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true);
 
374
@@ -971,15 +986,18 @@
 
375
 // static
 
376
 void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability(
 
377
     CommandUpdater* command_updater,
 
378
-    Profile* profile) {
 
379
+    Profile* profile,
 
380
+    bool started_in_chromeless) {
 
381
   IncognitoModePrefs::Availability incognito_availability =
 
382
       IncognitoModePrefs::GetAvailability(profile->GetPrefs());
 
383
   command_updater->UpdateCommandEnabled(
 
384
       IDC_NEW_WINDOW,
 
385
-      incognito_availability != IncognitoModePrefs::FORCED);
 
386
+      incognito_availability != IncognitoModePrefs::FORCED &&
 
387
+      !started_in_chromeless);
 
388
   command_updater->UpdateCommandEnabled(
 
389
       IDC_NEW_INCOGNITO_WINDOW,
 
390
-      incognito_availability != IncognitoModePrefs::DISABLED);
 
391
+      incognito_availability != IncognitoModePrefs::DISABLED &&
 
392
+      !started_in_chromeless);
 
393
 
 
394
   // Bookmark manager and settings page/subpages are forced to open in normal
 
395
   // mode. For this reason we disable these commands when incognito is forced.
 
396
@@ -987,7 +1005,8 @@
 
397
       incognito_availability != IncognitoModePrefs::FORCED;
 
398
   command_updater->UpdateCommandEnabled(
 
399
       IDC_SHOW_BOOKMARK_MANAGER,
 
400
-      browser_defaults::bookmarks_enabled && command_enabled);
 
401
+      browser_defaults::bookmarks_enabled && command_enabled &&
 
402
+      !started_in_chromeless);
 
403
   ExtensionService* extension_service = profile->GetExtensionService();
 
404
   bool enable_extensions =
 
405
       extension_service && extension_service->extensions_enabled();
 
406
@@ -999,7 +1018,10 @@
 
407
 }
 
408
 
 
409
 void BrowserCommandController::UpdateCommandsForIncognitoAvailability() {
 
410
-  UpdateSharedCommandsForIncognitoAvailability(&command_updater_, profile());
 
411
+  UpdateSharedCommandsForIncognitoAvailability(
 
412
+      &command_updater_,
 
413
+      profile(),
 
414
+      browser_->is_chromeless_mode());
 
415
 
 
416
   if (!IsShowingMainUI()) {
 
417
     command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, false);
 
418
@@ -1024,17 +1046,20 @@
 
419
 
 
420
   // Window management commands
 
421
   command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB,
 
422
-      !browser_->is_app() && CanDuplicateTab(browser_));
 
423
+      !browser_->is_chromeless_mode() && !browser_->is_app()
 
424
+          && CanDuplicateTab(browser_));
 
425
 
 
426
   // Page-related commands
 
427
   window()->SetStarredState(
 
428
       BookmarkTabHelper::FromWebContents(current_web_contents)->is_starred());
 
429
   window()->ZoomChangedForActiveTab(false);
 
430
   command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE,
 
431
-                                        CanViewSource(browser_));
 
432
+                                        CanViewSource(browser_)
 
433
+                                            && !browser_->is_chromeless_mode());
 
434
   command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION,
 
435
-                                        CanEmailPageLocation(browser_));
 
436
-  if (browser_->is_devtools())
 
437
+                                        CanEmailPageLocation(browser_)
 
438
+                                            && !browser_->is_chromeless_mode());
 
439
+  if (browser_->is_devtools() && browser_->is_chromeless_mode())
 
440
     command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false);
 
441
 
 
442
   // Changing the encoding is not possible on Chrome-internal webpages.
 
443
@@ -1050,7 +1075,8 @@
 
444
 #if !defined(OS_MACOSX)
 
445
   command_updater_.UpdateCommandEnabled(
 
446
       IDC_CREATE_SHORTCUTS,
 
447
-      CanCreateApplicationShortcuts(browser_));
 
448
+      CanCreateApplicationShortcuts(browser_)
 
449
+          && !browser_->is_chromeless_mode());
 
450
 #endif
 
451
 
 
452
   command_updater_.UpdateCommandEnabled(
 
453
@@ -1089,24 +1115,38 @@
 
454
 }
 
455
 
 
456
 void BrowserCommandController::UpdateCommandsForBookmarkEditing() {
 
457
+  bool started_in_chromeless =
 
458
+    CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeless)
 
459
+        || browser_->is_chromeless_mode();
 
460
+
 
461
   command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE,
 
462
-                                        CanBookmarkCurrentPage(browser_));
 
463
+                                        CanBookmarkCurrentPage(browser_)
 
464
+                                           && !started_in_chromeless);
 
465
   command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS,
 
466
-                                        CanBookmarkAllTabs(browser_));
 
467
+                                        CanBookmarkAllTabs(browser_)
 
468
+                                           && !started_in_chromeless);
 
469
   command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN,
 
470
-                                        true);
 
471
+                                        !started_in_chromeless);
 
472
 }
 
473
 
 
474
 void BrowserCommandController::UpdateCommandsForBookmarkBar() {
 
475
+  bool started_in_chromeless =
 
476
+    CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeless)
 
477
+        || browser_->is_chromeless_mode();
 
478
+
 
479
   command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
 
480
       browser_defaults::bookmarks_enabled &&
 
481
       !profile()->GetPrefs()->IsManagedPreference(prefs::kShowBookmarkBar) &&
 
482
-      IsShowingMainUI());
 
483
+      IsShowingMainUI() && !started_in_chromeless);
 
484
 }
 
485
 
 
486
 void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() {
 
487
+  const bool started_in_chromeless =
 
488
+    CommandLine::ForCurrentProcess()->HasSwitch(switches::kChromeless)
 
489
+    || browser_->is_chromeless_mode();
 
490
+
 
491
   UpdateSaveAsState();
 
492
-  UpdateOpenFileState(&command_updater_);
 
493
+  UpdateOpenFileState(&command_updater_, started_in_chromeless);
 
494
 }
 
495
 
 
496
 void BrowserCommandController::UpdateCommandsForFullscreenMode(
 
497
@@ -1160,7 +1200,8 @@
 
498
 #endif
 
499
 
 
500
   // Disable explicit fullscreen toggling when in metro snap mode.
 
501
-  bool fullscreen_enabled = fullscreen_mode != FULLSCREEN_METRO_SNAP;
 
502
+  bool fullscreen_enabled =
 
503
+    fullscreen_mode != FULLSCREEN_METRO_SNAP && !browser_->is_chromeless_mode();
 
504
 #if defined(OS_MACOSX)
 
505
   // The Mac implementation doesn't support switching to fullscreen while
 
506
   // a tab modal dialog is displayed.
 
507
@@ -1217,13 +1258,14 @@
 
508
 
 
509
 // static
 
510
 void BrowserCommandController::UpdateOpenFileState(
 
511
-    CommandUpdater* command_updater) {
 
512
+      CommandUpdater* command_updater, bool started_in_chromeless) {
 
513
   bool enabled = true;
 
514
   PrefService* local_state = g_browser_process->local_state();
 
515
   if (local_state)
 
516
     enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs);
 
517
 
 
518
-  command_updater->UpdateCommandEnabled(IDC_OPEN_FILE, enabled);
 
519
+  command_updater->UpdateCommandEnabled(IDC_OPEN_FILE,
 
520
+                                        enabled && !started_in_chromeless);
 
521
 }
 
522
 
 
523
 void BrowserCommandController::UpdateReloadStopState(bool is_loading,
 
524
Index: src/chrome/browser/ui/browser_command_controller.h
 
525
===================================================================
 
526
--- src/chrome/browser/ui/browser_command_controller.h  (revision 205727)
 
527
+++ src/chrome/browser/ui/browser_command_controller.h  (working copy)
 
528
@@ -68,13 +68,15 @@
 
529
   // outside code.
 
530
 
 
531
   // Updates the open-file state.
 
532
-  static void UpdateOpenFileState(CommandUpdater* command_updater);
 
533
+  static void UpdateOpenFileState(CommandUpdater* command_updater,
 
534
+                                  bool started_in_chromeless);
 
535
 
 
536
   // Update commands whose state depends on incognito mode availability and that
 
537
   // only depend on the profile.
 
538
   static void UpdateSharedCommandsForIncognitoAvailability(
 
539
       CommandUpdater* command_updater,
 
540
-      Profile* profile);
 
541
+      Profile* profile,
 
542
+      bool started_in_chromeless);
 
543
 
 
544
  private:
 
545
   class InterstitialObserver;
 
546
Index: src/chrome/browser/ui/browser_commands.cc
 
547
===================================================================
 
548
--- src/chrome/browser/ui/browser_commands.cc   (revision 205727)
 
549
+++ src/chrome/browser/ui/browser_commands.cc   (working copy)
 
550
@@ -462,6 +462,9 @@
 
551
 }
 
552
 
 
553
 void NewTab(Browser* browser) {
 
554
+  if (browser && browser->is_chromeless_mode())
 
555
+    return;
 
556
+
 
557
   content::RecordAction(UserMetricsAction("NewTab"));
 
558
   // TODO(asvitkine): This is invoked programmatically from several places.
 
559
   // Audit the code and change it so that the histogram only gets collected for
 
560
Index: src/chrome/browser/ui/browser_finder.cc
 
561
===================================================================
 
562
--- src/chrome/browser/ui/browser_finder.cc     (revision 205727)
 
563
+++ src/chrome/browser/ui/browser_finder.cc     (working copy)
 
564
@@ -24,6 +24,7 @@
 
565
 const int kMatchOriginalProfile         = 1 << 0;
 
566
 const int kMatchCanSupportWindowFeature = 1 << 1;
 
567
 const int kMatchTabbed                  = 1 << 2;
 
568
+const int kMatchNonChromeless           = 1 << 3;
 
569
 
 
570
 // Returns true if the specified |browser| matches the specified arguments.
 
571
 // |match_types| is a bitmask dictating what parameters to match:
 
572
@@ -51,8 +52,12 @@
 
573
   }
 
574
 
 
575
   if (match_types & kMatchTabbed)
 
576
-    return browser->is_type_tabbed();
 
577
+    return browser->is_type_tabbed() &&
 
578
+      !browser->is_chromeless_mode();
 
579
 
 
580
+  if (match_types & kMatchNonChromeless)
 
581
+    return !browser->is_chromeless_mode();
 
582
+
 
583
   return true;
 
584
 }
 
585
 
 
586
@@ -79,7 +84,7 @@
 
587
   BrowserList* browser_list_impl = BrowserList::GetInstance(desktop_type);
 
588
   if (!browser_list_impl)
 
589
     return NULL;
 
590
-  uint32 match_types = kMatchAny;
 
591
+  uint32 match_types = kMatchNonChromeless;
 
592
   if (match_tabbed)
 
593
     match_types |= kMatchTabbed;
 
594
   if (match_original_profiles)
 
595
Index: src/chrome/browser/ui/gtk/browser_window_gtk.cc
 
596
===================================================================
 
597
--- src/chrome/browser/ui/gtk/browser_window_gtk.cc     (revision 205727)
 
598
+++ src/chrome/browser/ui/gtk/browser_window_gtk.cc     (working copy)
 
599
@@ -301,6 +301,13 @@
 
600
     gtk_window_util::SetWindowCustomClass(window_,
 
601
         std::string(gdk_get_program_class()) + " (" + user_data_dir + ")");
 
602
   }
 
603
+  else if (browser_->is_chromeless_mode()) {
 
604
+    // The web application's url associated with the chromeless launch
 
605
+    // is appended for later reference.
 
606
+    // TODO: very so-so, find a better approach.
 
607
+    gtk_window_util::SetWindowCustomClass(window_,
 
608
+        web_app::GetWMClassFromAppName("chromeless"));
 
609
+  }
 
610
 
 
611
   // For popups, we initialize widgets then set the window geometry, because
 
612
   // popups need the widgets inited before they can set the window size
 
613
@@ -889,7 +896,7 @@
 
614
 }
 
615
 
 
616
 void BrowserWindowGtk::SetFocusToLocationBar(bool select_all) {
 
617
-  if (!IsFullscreen())
 
618
+  if (!IsFullscreen() && IsToolbarSupported())
 
619
     GetLocationBar()->FocusLocation(select_all);
 
620
 }
 
621
 
 
622
@@ -1188,6 +1195,20 @@
 
623
   gtk_util::SetWindowIcon(window_, browser_->profile());
 
624
 }
 
625
 
 
626
+void BrowserWindowGtk::HandleTabCountChange(bool is_deleting) {
 
627
+  if (browser_ == NULL || browser_->tab_strip_model() == NULL)
 
628
+    return;
 
629
+
 
630
+  int count = browser_->tab_strip_model()->count();
 
631
+  const int HIDE_TAB_COUNT = is_deleting ? 2 : 1;
 
632
+  if (count == HIDE_TAB_COUNT) {
 
633
+    tabstrip_->Hide();
 
634
+  }
 
635
+  else {
 
636
+    tabstrip_->Show();
 
637
+  }
 
638
+}
 
639
+
 
640
 void BrowserWindowGtk::TabDetachedAt(WebContents* contents, int index) {
 
641
   // We use index here rather than comparing |contents| because by this time
 
642
   // the model has already removed |contents| from its list, so
 
643
@@ -1198,8 +1219,25 @@
 
644
     UpdateDevToolsForContents(NULL);
 
645
   }
 
646
   contents_container_->DetachTab(contents);
 
647
+
 
648
+  if (browser_->is_chromeless_mode())
 
649
+    HandleTabCountChange(false);
 
650
 }
 
651
 
 
652
+void BrowserWindowGtk::TabInsertedAt(content::WebContents* contents,
 
653
+                                     int index,
 
654
+                                     bool foreground) {
 
655
+  if (browser_->is_chromeless_mode())
 
656
+    HandleTabCountChange(false);
 
657
+}
 
658
+
 
659
+void BrowserWindowGtk::TabClosingAt(TabStripModel* tab_strip_model,
 
660
+                                    content::WebContents* contents,
 
661
+                                    int index) {
 
662
+  if (browser_->is_chromeless_mode())
 
663
+    HandleTabCountChange(true);
 
664
+}
 
665
+
 
666
 void BrowserWindowGtk::ActiveTabChanged(WebContents* old_contents,
 
667
                                         WebContents* new_contents,
 
668
                                         int index,
 
669
@@ -2152,8 +2190,12 @@
 
670
 }
 
671
 
 
672
 void BrowserWindowGtk::ShowSupportedWindowFeatures() {
 
673
-  if (IsTabStripSupported())
 
674
-    tabstrip_->Show();
 
675
+  if (IsTabStripSupported()) {
 
676
+    if (browser_->is_chromeless_mode())
 
677
+      HandleTabCountChange(false);
 
678
+    else
 
679
+      tabstrip_->Show();
 
680
+  }
 
681
 
 
682
   if (IsToolbarSupported()) {
 
683
     toolbar_->Show();
 
684
@@ -2166,8 +2208,12 @@
 
685
 }
 
686
 
 
687
 void BrowserWindowGtk::HideUnsupportedWindowFeatures() {
 
688
-  if (!IsTabStripSupported())
 
689
-    tabstrip_->Hide();
 
690
+  if (!IsTabStripSupported()) {
 
691
+    if (browser_->is_chromeless_mode())
 
692
+      HandleTabCountChange(false);
 
693
+    else
 
694
+      tabstrip_->Hide();
 
695
+  }
 
696
 
 
697
   if (!IsToolbarSupported())
 
698
     toolbar_->Hide();
 
699
@@ -2207,7 +2253,8 @@
 
700
 
 
701
 bool BrowserWindowGtk::UseCustomFrame() const {
 
702
   // We don't use the custom frame for app mode windows or app window popups.
 
703
-  return use_custom_frame_pref_.GetValue() && !browser_->is_app();
 
704
+  return use_custom_frame_pref_.GetValue() &&
 
705
+      !browser_->is_app() && !browser_->is_chromeless_mode();
 
706
 }
 
707
 
 
708
 void BrowserWindowGtk::PlaceBookmarkBar(bool is_floating) {
 
709
Index: src/chrome/browser/ui/gtk/browser_window_gtk.h
 
710
===================================================================
 
711
--- src/chrome/browser/ui/gtk/browser_window_gtk.h      (revision 205727)
 
712
+++ src/chrome/browser/ui/gtk/browser_window_gtk.h      (working copy)
 
713
@@ -188,6 +188,13 @@
 
714
                                 int index,
 
715
                                 int reason) OVERRIDE;
 
716
 
 
717
+  virtual void TabInsertedAt(content::WebContents* contents,
 
718
+                             int index,
 
719
+                             bool foreground) OVERRIDE;
 
720
+  virtual void TabClosingAt(TabStripModel* tab_strip_model,
 
721
+                            content::WebContents* contents,
 
722
+                            int index) OVERRIDE;
 
723
+
 
724
   // Overridden from ActiveWindowWatcherXObserver.
 
725
   virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
 
726
 
 
727
@@ -331,6 +338,9 @@
 
728
   // ctrl-l, etc.).
 
729
   void ConnectAccelerators();
 
730
 
 
731
+  // 
 
732
+  void HandleTabCountChange(bool is_deleting);
 
733
+
 
734
   // Whether we should draw the tab background instead of the theme_frame
 
735
   // background because this window is a popup.
 
736
   bool UsingCustomPopupFrame() const;
 
737
Index: src/chrome/browser/ui/gtk/global_menu_bar.cc
 
738
===================================================================
 
739
--- src/chrome/browser/ui/gtk/global_menu_bar.cc        (revision 205727)
 
740
+++ src/chrome/browser/ui/gtk/global_menu_bar.cc        (working copy)
 
741
@@ -25,35 +25,43 @@
 
742
 #include "ui/base/gtk/menu_label_accelerator_util.h"
 
743
 #include "ui/base/l10n/l10n_util.h"
 
744
 
 
745
+typedef bool (*GlobalMenuBarVisibilityHandler) (Browser * browser);
 
746
+
 
747
 struct GlobalMenuBarCommand {
 
748
   int str_id;
 
749
   int command;
 
750
   int tag;
 
751
+  GlobalMenuBarVisibilityHandler visibility_handler;
 
752
 };
 
753
 
 
754
 namespace {
 
755
 
 
756
+bool GlobalMenuBarVisibilityHandler_NotInChromelessMode(
 
757
+    Browser * browser) {
 
758
+  return browser && !browser->is_chromeless_mode();
 
759
+}
 
760
+
 
761
 const int MENU_SEPARATOR =-1;
 
762
 const int MENU_END = -2;
 
763
 const int MENU_DISABLED_LABEL = -3;
 
764
 
 
765
 GlobalMenuBarCommand file_menu[] = {
 
766
-  { IDS_NEW_TAB, IDC_NEW_TAB },
 
767
-  { IDS_NEW_WINDOW, IDC_NEW_WINDOW },
 
768
-  { IDS_NEW_INCOGNITO_WINDOW, IDC_NEW_INCOGNITO_WINDOW },
 
769
-  { IDS_REOPEN_CLOSED_TABS_LINUX, IDC_RESTORE_TAB },
 
770
-  { IDS_OPEN_FILE_LINUX, IDC_OPEN_FILE },
 
771
-  { IDS_OPEN_LOCATION_LINUX, IDC_FOCUS_LOCATION },
 
772
+  { IDS_NEW_TAB, IDC_NEW_TAB, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
773
+  { IDS_NEW_WINDOW, IDC_NEW_WINDOW, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
774
+  { IDS_NEW_INCOGNITO_WINDOW, IDC_NEW_INCOGNITO_WINDOW, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
775
+  { IDS_REOPEN_CLOSED_TABS_LINUX, IDC_RESTORE_TAB, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
776
+  { IDS_OPEN_FILE_LINUX, IDC_OPEN_FILE, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
777
+  { IDS_OPEN_LOCATION_LINUX, IDC_FOCUS_LOCATION, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
778
 
 
779
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
780
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
781
 
 
782
-  { IDS_CREATE_SHORTCUTS, IDC_CREATE_SHORTCUTS },
 
783
+  { IDS_CREATE_SHORTCUTS, IDC_CREATE_SHORTCUTS, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
784
 
 
785
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
786
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
787
 
 
788
   { IDS_CLOSE_WINDOW_LINUX, IDC_CLOSE_WINDOW },
 
789
   { IDS_CLOSE_TAB_LINUX, IDC_CLOSE_TAB },
 
790
-  { IDS_SAVE_PAGE, IDC_SAVE_PAGE },
 
791
+  { IDS_SAVE_PAGE, IDC_SAVE_PAGE, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
792
 
 
793
   { MENU_SEPARATOR, MENU_SEPARATOR },
 
794
 
 
795
@@ -71,17 +79,17 @@
 
796
 
 
797
   { IDS_FIND, IDC_FIND },
 
798
 
 
799
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
800
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
801
 
 
802
-  { IDS_PREFERENCES, IDC_OPTIONS },
 
803
+  { IDS_PREFERENCES, IDC_OPTIONS, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
804
 
 
805
   { MENU_END, MENU_END }
 
806
 };
 
807
 
 
808
 GlobalMenuBarCommand view_menu[] = {
 
809
-  { IDS_SHOW_BOOKMARK_BAR, IDC_SHOW_BOOKMARK_BAR },
 
810
+  { IDS_SHOW_BOOKMARK_BAR, IDC_SHOW_BOOKMARK_BAR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
811
 
 
812
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
813
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
814
 
 
815
   { IDS_STOP_MENU_LINUX, IDC_STOP },
 
816
   { IDS_RELOAD_MENU_LINUX, IDC_RELOAD },
 
817
@@ -97,48 +105,48 @@
 
818
 };
 
819
 
 
820
 GlobalMenuBarCommand history_menu[] = {
 
821
-  { IDS_HISTORY_HOME_LINUX, IDC_HOME },
 
822
-  { IDS_HISTORY_BACK_LINUX, IDC_BACK },
 
823
-  { IDS_HISTORY_FORWARD_LINUX, IDC_FORWARD },
 
824
+  { IDS_HISTORY_HOME_LINUX, IDC_HOME, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
825
+  { IDS_HISTORY_BACK_LINUX, IDC_BACK, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
826
+  { IDS_HISTORY_FORWARD_LINUX, IDC_FORWARD, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
827
 
 
828
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
829
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
830
 
 
831
   { IDS_HISTORY_VISITED_LINUX, MENU_DISABLED_LABEL,
 
832
-    GlobalMenuBar::TAG_MOST_VISITED_HEADER },
 
833
+    GlobalMenuBar::TAG_MOST_VISITED_HEADER, GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
834
 
 
835
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
836
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
837
 
 
838
   { IDS_HISTORY_CLOSED_LINUX, MENU_DISABLED_LABEL,
 
839
-    GlobalMenuBar::TAG_RECENTLY_CLOSED_HEADER },
 
840
+    GlobalMenuBar::TAG_RECENTLY_CLOSED_HEADER, GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
841
 
 
842
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
843
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
844
 
 
845
-  { IDS_SHOWFULLHISTORY_LINK, IDC_SHOW_HISTORY },
 
846
+  { IDS_SHOWFULLHISTORY_LINK, IDC_SHOW_HISTORY, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
847
 
 
848
   { MENU_END, MENU_END }
 
849
 };
 
850
 
 
851
 GlobalMenuBarCommand tools_menu[] = {
 
852
-  { IDS_SHOW_DOWNLOADS, IDC_SHOW_DOWNLOADS },
 
853
-  { IDS_SHOW_HISTORY, IDC_SHOW_HISTORY },
 
854
-  { IDS_SHOW_EXTENSIONS, IDC_MANAGE_EXTENSIONS },
 
855
+  { IDS_SHOW_DOWNLOADS, IDC_SHOW_DOWNLOADS, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
856
+  { IDS_SHOW_HISTORY, IDC_SHOW_HISTORY, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
857
+  { IDS_SHOW_EXTENSIONS, IDC_MANAGE_EXTENSIONS, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
858
 
 
859
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
860
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
861
 
 
862
-  { IDS_TASK_MANAGER, IDC_TASK_MANAGER },
 
863
-  { IDS_CLEAR_BROWSING_DATA, IDC_CLEAR_BROWSING_DATA },
 
864
+  { IDS_TASK_MANAGER, IDC_TASK_MANAGER, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
865
+  { IDS_CLEAR_BROWSING_DATA, IDC_CLEAR_BROWSING_DATA, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
866
 
 
867
-  { MENU_SEPARATOR, MENU_SEPARATOR },
 
868
+  { MENU_SEPARATOR, MENU_SEPARATOR, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
869
 
 
870
-  { IDS_VIEW_SOURCE, IDC_VIEW_SOURCE },
 
871
-  { IDS_DEV_TOOLS, IDC_DEV_TOOLS },
 
872
-  { IDS_DEV_TOOLS_CONSOLE, IDC_DEV_TOOLS_CONSOLE },
 
873
+  { IDS_VIEW_SOURCE, IDC_VIEW_SOURCE, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
874
+  { IDS_DEV_TOOLS, IDC_DEV_TOOLS, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
875
+  { IDS_DEV_TOOLS_CONSOLE, IDC_DEV_TOOLS_CONSOLE, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
876
 
 
877
   { MENU_END, MENU_END }
 
878
 };
 
879
 
 
880
 GlobalMenuBarCommand help_menu[] = {
 
881
-  { IDS_FEEDBACK, IDC_FEEDBACK },
 
882
+  { IDS_FEEDBACK, IDC_FEEDBACK, int(), GlobalMenuBarVisibilityHandler_NotInChromelessMode },
 
883
   { IDS_HELP_PAGE , IDC_HELP_PAGE_VIA_MENU },
 
884
   { MENU_END, MENU_END }
 
885
 };
 
886
@@ -191,11 +199,12 @@
 
887
   }
 
888
 
 
889
   pref_change_registrar_.Init(browser_->profile()->GetPrefs());
 
890
-  pref_change_registrar_.Add(
 
891
-      prefs::kShowBookmarkBar,
 
892
-      base::Bind(&GlobalMenuBar::OnBookmarkBarVisibilityChanged,
 
893
-                 base::Unretained(this)));
 
894
-  OnBookmarkBarVisibilityChanged();
 
895
+  if (! browser_->is_chromeless_mode()) {
 
896
+    pref_change_registrar_.Add(
 
897
+        prefs::kShowBookmarkBar,
 
898
+        base::Bind(&GlobalMenuBar::OnBookmarkBarVisibilityChanged,
 
899
+                   base::Unretained(this)));
 
900
+ }
 
901
 }
 
902
 
 
903
 GlobalMenuBar::~GlobalMenuBar() {
 
904
@@ -218,8 +227,22 @@
 
905
     std::map<int, GtkWidget*>* id_to_menu_item,
 
906
     GlobalMenuBarCommand* commands,
 
907
     GlobalMenuOwner* owner) {
 
908
+  // first pass to count the number of "visible" items
 
909
+  size_t count = 0;
 
910
+  for (int i = 0; commands[i].str_id != MENU_END; ++i) {
 
911
+    if (!commands[i].visibility_handler || commands[i].visibility_handler(browser_)) {
 
912
+      count++;
 
913
+    }
 
914
+  }
 
915
+  if (0 == count) {
 
916
+    return;
 
917
+  }
 
918
+
 
919
   GtkWidget* menu = gtk_menu_new();
 
920
   for (int i = 0; commands[i].str_id != MENU_END; ++i) {
 
921
+    if (commands[i].visibility_handler && !commands[i].visibility_handler(browser_)) {
 
922
+      continue;
 
923
+    }
 
924
     GtkWidget* menu_item = BuildMenuItem(
 
925
         commands[i].str_id, commands[i].command, commands[i].tag,
 
926
         id_to_menu_item, menu);
 
927
Index: src/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc
 
928
===================================================================
 
929
--- src/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc     (revision 205727)
 
930
+++ src/chrome/browser/ui/gtk/tabs/tab_strip_gtk.cc     (working copy)
 
931
@@ -786,9 +786,12 @@
 
932
   g_signal_connect(tabstrip_.get(), "drag-data-received",
 
933
                    G_CALLBACK(OnDragDataReceivedThunk), this);
 
934
 
 
935
-  newtab_button_.reset(MakeNewTabButton());
 
936
-  newtab_surface_bounds_.SetRect(0, 0, newtab_button_->SurfaceWidth(),
 
937
-                                 newtab_button_->SurfaceHeight());
 
938
+  if (window_ && window_->browser() &&
 
939
+          ! window_->browser()->is_chromeless_mode()) {
 
940
+    newtab_button_.reset(MakeNewTabButton());
 
941
+    newtab_surface_bounds_.SetRect(0, 0, newtab_button_->SurfaceWidth(),
 
942
+                                   newtab_button_->SurfaceHeight());
 
943
+  }
 
944
 
 
945
   gtk_widget_show_all(tabstrip_.get());
 
946
 
 
947
@@ -1461,6 +1464,9 @@
 
948
 
 
949
 void TabStripGtk::LayoutNewTabButton(double last_tab_right,
 
950
                                      double unselected_width) {
 
951
+  if (window_ && window_->browser() && window_->browser()->is_chromeless_mode())
 
952
+    return;
 
953
+
 
954
   GtkWidget* toplevel = gtk_widget_get_ancestor(widget(), GTK_TYPE_WINDOW);
 
955
   bool is_maximized = false;
 
956
   if (toplevel) {
 
957
@@ -1514,8 +1520,10 @@
 
958
   int available_width = tabstrip_allocation.width;
 
959
   if (available_width_for_tabs_ < 0) {
 
960
     available_width = bounds_.width();
 
961
-    available_width -=
 
962
+    if (newtab_button_.get() != NULL) {
 
963
+      available_width -=
 
964
         (kNewTabButtonHOffset + newtab_button_->WidgetAllocation().width);
 
965
+    }
 
966
   } else {
 
967
     // Interesting corner case: if |available_width_for_tabs_| > the result
 
968
     // of the calculation in the conditional arm above, the strip is in
 
969
@@ -2073,8 +2081,11 @@
 
970
   gdk_region_union_with_rect(event->region, &event->area);
 
971
 
 
972
   // Paint the New Tab button.
 
973
-  gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()),
 
974
-      newtab_button_->widget(), event);
 
975
+  if (newtab_button_.get() != NULL) {
 
976
+    // Paint the New Tab button.
 
977
+    gtk_container_propagate_expose(GTK_CONTAINER(tabstrip_.get()),
 
978
+        newtab_button_->widget(), event);
 
979
+  }
 
980
 
 
981
   // Paint the tabs in reverse order, so they stack to the left.
 
982
   TabGtk* selected_tab = NULL;
 
983
@@ -2271,6 +2282,9 @@
 
984
 }
 
985
 
 
986
 void TabStripGtk::SetNewTabButtonBackground() {
 
987
+  if (newtab_button_.get() == NULL) {
 
988
+    return;
 
989
+  }
 
990
   SkColor color = theme_service_->GetColor(
 
991
       ThemeProperties::COLOR_BUTTON_BACKGROUND);
 
992
   SkBitmap background = theme_service_->GetImageNamed(
 
993
Index: src/chrome/browser/ui/startup/startup_browser_creator_impl.cc
 
994
===================================================================
 
995
--- src/chrome/browser/ui/startup/startup_browser_creator_impl.cc       (revision 205727)
 
996
+++ src/chrome/browser/ui/startup/startup_browser_creator_impl.cc       (working copy)
 
997
@@ -444,6 +444,16 @@
 
998
   }
 
999
 }
 
1000
 
 
1001
+bool StartupBrowserCreatorImpl::IsChromelessLaunch(std::string* url)
 
1002
+{
 
1003
+  if (command_line_.HasSwitch(switches::kChromeless)) {
 
1004
+    if (url)
 
1005
+      *url = command_line_.GetSwitchValueASCII(switches::kChromeless);
 
1006
+    return true;
 
1007
+  }
 
1008
+  return false;
 
1009
+}
 
1010
+
 
1011
 bool StartupBrowserCreatorImpl::IsAppLaunch(std::string* app_url,
 
1012
                                             std::string* app_id) {
 
1013
   if (command_line_.HasSwitch(switches::kApp)) {
 
1014
@@ -588,6 +598,12 @@
 
1015
   }
 
1016
 #endif
 
1017
 
 
1018
+  if (IsChromelessLaunch(NULL)) {
 
1019
+    // Open user-specified URLs like pinned tabs and startup tabs.
 
1020
+    if (ProcessSpecifiedURLs(urls_to_open))
 
1021
+      return;
 
1022
+  }
 
1023
+
 
1024
   if (process_startup && ProcessStartupURLs(urls_to_open)) {
 
1025
     // ProcessStartupURLs processed the urls, nothing else to do.
 
1026
     return;
 
1027
@@ -730,7 +746,8 @@
 
1028
   // mode. Also, no pages should be opened automatically if the session
 
1029
   // crashed. Otherwise it might trigger another crash, locking the user out of
 
1030
   // chrome. The crash infobar is shown in this case.
 
1031
-  if (!IncognitoModePrefs::ShouldLaunchIncognito(command_line_,
 
1032
+  if (!IsChromelessLaunch(NULL) &&
 
1033
+      !IncognitoModePrefs::ShouldLaunchIncognito(command_line_,
 
1034
                                                  profile_->GetPrefs()) &&
 
1035
       !HasPendingUncleanExit(profile_)) {
 
1036
     tabs = PinnedTabCodec::ReadPinnedTabs(profile_);
 
1037
@@ -811,6 +828,12 @@
 
1038
   if (!profile_ && browser)
 
1039
     profile_ = browser->profile();
 
1040
 
 
1041
+  if (IsChromelessLaunch(NULL)) {
 
1042
+    browser = new Browser(Browser::CreateParams::CreateChromeless(profile_,
 
1043
+                             browser ? browser->host_desktop_type()
 
1044
+                               : chrome::HOST_DESKTOP_TYPE_NATIVE));
 
1045
+  }
 
1046
+
 
1047
   if (!browser || !browser->is_type_tabbed()) {
 
1048
     // The startup code only executes for browsers launched in desktop mode.
 
1049
     // i.e. HOST_DESKTOP_TYPE_NATIVE. Ash should never get here.
 
1050
@@ -890,6 +913,11 @@
 
1051
   if (!browser || !profile_ || browser->tab_strip_model()->count() == 0)
 
1052
     return;
 
1053
 
 
1054
+  // We consider that being in a chromeless launch, we are to minimize
 
1055
+  // as much as possible the most obvious "classic" Chromium behavior.
 
1056
+  if (IsChromelessLaunch(NULL))
 
1057
+      return;
 
1058
+
 
1059
   if (HasPendingUncleanExit(browser->profile()))
 
1060
     SessionCrashedInfoBarDelegate::Create(browser);
 
1061
 
 
1062
Index: src/chrome/browser/ui/startup/startup_browser_creator_impl.h
 
1063
===================================================================
 
1064
--- src/chrome/browser/ui/startup/startup_browser_creator_impl.h        (revision 205727)
 
1065
+++ src/chrome/browser/ui/startup/startup_browser_creator_impl.h        (working copy)
 
1066
@@ -79,6 +79,11 @@
 
1067
   FRIEND_TEST_ALL_PREFIXES(BrowserTest, RestorePinnedTabs);
 
1068
   FRIEND_TEST_ALL_PREFIXES(BrowserTest, AppIdSwitch);
 
1069
 
 
1070
+  // If the process was launched with the chromeless command line flag,
 
1071
+  // e.g. --chromeless=http://www.google.com/ return true.
 
1072
+  // In this case |url| is populated if they're non-null.
 
1073
+  bool IsChromelessLaunch(std::string* url);
 
1074
+
 
1075
   // Extracts optional application window size passed in command line.
 
1076
   void ExtractOptionalAppWindowSize(gfx::Rect* bounds);
 
1077
 
 
1078
Index: src/chrome/common/chrome_switches.cc
 
1079
===================================================================
 
1080
--- src/chrome/common/chrome_switches.cc        (revision 205727)
 
1081
+++ src/chrome/common/chrome_switches.cc        (working copy)
 
1082
@@ -149,6 +149,9 @@
 
1083
 // as a dependent process of the Chrome Frame plugin.
 
1084
 const char kChromeFrame[]                   = "chrome-frame";
 
1085
 
 
1086
+// Specifies a given URL to be opened in a chromeless mode.
 
1087
+const char kChromeless[]                    = "chromeless";
 
1088
+
 
1089
 // Tells chrome to load the specified version of chrome.dll on Windows. If this
 
1090
 // version cannot be loaded, Chrome will exit.
 
1091
 const char kChromeVersion[]                 = "chrome-version";
 
1092
Index: src/chrome/common/chrome_switches.h
 
1093
===================================================================
 
1094
--- src/chrome/common/chrome_switches.h (revision 205727)
 
1095
+++ src/chrome/common/chrome_switches.h (working copy)
 
1096
@@ -57,6 +57,7 @@
 
1097
 extern const char kCheckForUpdateIntervalSec[];
 
1098
 extern const char kCheckCloudPrintConnectorPolicy[];
 
1099
 extern const char kChromeFrame[];
 
1100
+extern const char kChromeless[];
 
1101
 extern const char kChromeVersion[];
 
1102
 extern const char kCipherSuiteBlacklist[];
 
1103
 extern const char kClearTokenService[];
 
1104
Index: src/chrome/common/extensions/api/extension.json
 
1105
===================================================================
 
1106
--- src/chrome/common/extensions/api/extension.json     (revision 205727)
 
1107
+++ src/chrome/common/extensions/api/extension.json     (working copy)
 
1108
@@ -138,6 +138,32 @@
 
1109
         }
 
1110
       },
 
1111
       {
 
1112
+        "name": "isChromelessWindow",
 
1113
+        "type": "function",
 
1114
+        "unprivileged": true,
 
1115
+        "description": "Checks is a given extension runs part of a chromeless window.",
 
1116
+        "parameters": [
 
1117
+          {
 
1118
+            "type": "integer",
 
1119
+            "name": "tabId",
 
1120
+            "optional": true,
 
1121
+            "description": "The tab id corresponding to the window to restrict the request to."
 
1122
+          }
 
1123
+          ,
 
1124
+          {
 
1125
+            "type": "function",
 
1126
+            "name": "callback",
 
1127
+            "parameters": [
 
1128
+              {
 
1129
+                "name": "isChromelessWindow",
 
1130
+                "type": "boolean",
 
1131
+                "description": "True if the extension runs part of a chromeless window, false otherwise."
 
1132
+              }
 
1133
+            ]
 
1134
+          }
 
1135
+        ]
 
1136
+      },
 
1137
+      {
 
1138
         "name": "isAllowedIncognitoAccess",
 
1139
         "type": "function",
 
1140
         "description": "Retrieves the state of the extension's access to Incognito-mode (as determined by the user-controlled 'Allowed in Incognito' checkbox.",