~ps-jenkins/unity-chromium-extension/trusty-proposed

« back to all changes in this revision

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

  • Committer: CI bot
  • Author(s): Justin McPherson
  • Date: 2014-02-17 23:43:23 UTC
  • mfrom: (239.2.1 remove-patches)
  • Revision ID: ps-jenkins@lists.canonical.com-20140217234323-4pw656wfrooeinde
Chromium patches are no longer maintained in this repo, remove them to avoid confusion. 

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.",