Run Tizen Webapps in single process mode
[platform/framework/web/crosswalk-tizen.git] / atom / browser / api / atom_api_window.cc
1 // Copyright (c) 2013 GitHub, Inc.
2 // Use of this source code is governed by the MIT license that can be
3 // found in the LICENSE file.
4
5 #include "atom/browser/api/atom_api_window.h"
6 #include "atom/common/native_mate_converters/value_converter.h"
7
8 #include "atom/browser/api/atom_api_browser_view.h"
9 #include "atom/browser/api/atom_api_menu.h"
10 #include "atom/browser/api/atom_api_web_contents.h"
11 #include "atom/browser/browser.h"
12 #include "atom/browser/native_window.h"
13 #include "atom/common/native_mate_converters/callback.h"
14 #include "atom/common/native_mate_converters/file_path_converter.h"
15 #include "atom/common/native_mate_converters/gfx_converter.h"
16 #include "atom/common/native_mate_converters/gurl_converter.h"
17 #include "atom/common/native_mate_converters/image_converter.h"
18 #include "atom/common/native_mate_converters/string16_converter.h"
19 #include "atom/common/options_switches.h"
20 #include "base/command_line.h"
21 #include "base/threading/thread_task_runner_handle.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/common/content_switches.h"
24 #include "native_mate/constructor.h"
25 #include "native_mate/dictionary.h"
26 #include "tizen/common/env_variables.h"
27 #include "ui/gfx/geometry/rect.h"
28
29 #if defined(TOOLKIT_VIEWS)
30 #include "atom/browser/native_window_views.h"
31 #endif
32
33 #if defined(OS_WIN)
34 #include "atom/browser/ui/win/taskbar_host.h"
35 #include "ui/base/win/shell.h"
36 #endif
37
38 #include "atom/common/node_includes.h"
39
40 #if defined(OS_WIN)
41 namespace mate {
42
43 template<>
44 struct Converter<atom::TaskbarHost::ThumbarButton> {
45   static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
46                      atom::TaskbarHost::ThumbarButton* out) {
47     mate::Dictionary dict;
48     if (!ConvertFromV8(isolate, val, &dict))
49       return false;
50     dict.Get("click", &(out->clicked_callback));
51     dict.Get("tooltip", &(out->tooltip));
52     dict.Get("flags", &out->flags);
53     return dict.Get("icon", &(out->icon));
54   }
55 };
56
57 }  // namespace mate
58 #endif
59
60 namespace atom {
61
62 namespace api {
63
64 namespace {
65
66 // Converts binary data to Buffer.
67 v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
68   auto buffer = node::Buffer::Copy(isolate, static_cast<char*>(val), size);
69   if (buffer.IsEmpty())
70     return v8::Null(isolate);
71   else
72     return buffer.ToLocalChecked();
73 }
74
75 }  // namespace
76
77
78 Window::Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
79                const mate::Dictionary& options) {
80   mate::Handle<class WebContents> web_contents;
81   // If no WebContents was passed to the constructor, create it from options.
82   if (!options.Get("webContents", &web_contents)) {
83     // Use options.webPreferences to create WebContents.
84     mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
85     options.Get(options::kWebPreferences, &web_preferences);
86
87     // Copy the backgroundColor to webContents.
88     v8::Local<v8::Value> value;
89     if (options.Get(options::kBackgroundColor, &value))
90       web_preferences.Set(options::kBackgroundColor, value);
91
92     v8::Local<v8::Value> transparent;
93     if (options.Get("transparent", &transparent))
94       web_preferences.Set("transparent", transparent);
95
96     // Offscreen windows are always created frameless.
97     bool offscreen;
98     if (web_preferences.Get("offscreen", &offscreen) && offscreen) {
99       auto window_options = const_cast<mate::Dictionary&>(options);
100       window_options.Set(options::kFrame, false);
101     }
102
103     // Creates the WebContents used by BrowserWindow.
104     web_contents = WebContents::Create(isolate, web_preferences);
105   }
106
107   Init(isolate, wrapper, options, web_contents);
108 }
109
110 void Window::Init(v8::Isolate* isolate,
111                   v8::Local<v8::Object> wrapper,
112                   const mate::Dictionary& options,
113                   mate::Handle<class WebContents> web_contents) {
114   web_contents_.Reset(isolate, web_contents.ToV8());
115   api_web_contents_ = web_contents.get();
116
117   // Keep a copy of the options for later use.
118   mate::Dictionary(isolate, web_contents->GetWrapper()).Set(
119       "browserWindowOptions", options);
120
121   // The parent window.
122   mate::Handle<Window> parent;
123   if (options.Get("parent", &parent))
124     parent_window_.Reset(isolate, parent.ToV8());
125
126   // Creates BrowserWindow.
127   window_.reset(NativeWindow::Create(
128       web_contents->managed_web_contents(),
129       options,
130       parent.IsEmpty() ? nullptr : parent->window_.get()));
131   web_contents->SetOwnerWindow(window_.get());
132
133 #if defined(TOOLKIT_VIEWS)
134   // Sets the window icon.
135   mate::Handle<NativeImage> icon;
136   if (options.Get(options::kIcon, &icon))
137     SetIcon(icon);
138 #endif
139
140   window_->InitFromOptions(options);
141   window_->AddObserver(this);
142
143   InitWith(isolate, wrapper);
144   AttachAsUserData(window_.get());
145
146   // We can only append this window to parent window's child windows after this
147   // window's JS wrapper gets initialized.
148   if (!parent.IsEmpty())
149     parent->child_windows_.Set(isolate, ID(), wrapper);
150 }
151
152 Window::~Window() {
153   if (!window_->IsClosed())
154     window_->CloseContents(nullptr);
155
156   // Destroy the native window in next tick because the native code might be
157   // iterating all windows.
158   base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release());
159 }
160
161 void Window::WillCloseWindow(bool* prevent_default) {
162   *prevent_default = Emit("close");
163 }
164
165 void Window::WillDestroyNativeObject() {
166   // Close all child windows before closing current window.
167   if (!::tizen::is_single_process)
168     v8::Locker locker(isolate());
169   v8::HandleScope handle_scope(isolate());
170   for (v8::Local<v8::Value> value : child_windows_.Values(isolate())) {
171     mate::Handle<Window> child;
172     if (mate::ConvertFromV8(isolate(), value, &child))
173       child->window_->CloseImmediately();
174   }
175 }
176
177 void Window::OnWindowClosed() {
178   api_web_contents_->DestroyWebContents();
179
180   RemoveFromWeakMap();
181   window_->RemoveObserver(this);
182
183   // We can not call Destroy here because we need to call Emit first, but we
184   // also do not want any method to be used, so just mark as destroyed here.
185   MarkDestroyed();
186
187   Emit("closed");
188
189   RemoveFromParentChildWindows();
190
191   // Destroy the native class when window is closed.
192   base::ThreadTaskRunnerHandle::Get()->PostTask(
193       FROM_HERE, GetDestroyClosure());
194 }
195
196 void Window::OnWindowEndSession() {
197   Emit("session-end");
198 }
199
200 void Window::OnWindowBlur() {
201   Emit("blur");
202 }
203
204 void Window::OnWindowFocus() {
205   Emit("focus");
206 }
207
208 void Window::OnWindowShow() {
209   Emit("show");
210 }
211
212 void Window::OnWindowHide() {
213   Emit("hide");
214 }
215
216 void Window::OnReadyToShow() {
217   Emit("ready-to-show");
218 }
219
220 void Window::OnWindowMaximize() {
221   Emit("maximize");
222 }
223
224 void Window::OnWindowUnmaximize() {
225   Emit("unmaximize");
226 }
227
228 void Window::OnWindowMinimize() {
229   Emit("minimize");
230 }
231
232 void Window::OnWindowRestore() {
233   Emit("restore");
234 }
235
236 void Window::OnWindowResize() {
237   Emit("resize");
238 }
239
240 void Window::OnWindowMove() {
241   Emit("move");
242 }
243
244 void Window::OnWindowMoved() {
245   Emit("moved");
246 }
247
248 void Window::OnWindowEnterFullScreen() {
249   Emit("enter-full-screen");
250 }
251
252 void Window::OnWindowLeaveFullScreen() {
253   Emit("leave-full-screen");
254 }
255
256 void Window::OnWindowScrollTouchBegin() {
257   Emit("scroll-touch-begin");
258 }
259
260 void Window::OnWindowScrollTouchEnd() {
261   Emit("scroll-touch-end");
262 }
263
264 void Window::OnWindowScrollTouchEdge() {
265   Emit("scroll-touch-edge");
266 }
267
268 void Window::OnWindowSwipe(const std::string& direction) {
269   Emit("swipe", direction);
270 }
271
272 void Window::OnWindowSheetBegin() {
273   Emit("sheet-begin");
274 }
275
276 void Window::OnWindowSheetEnd() {
277   Emit("sheet-end");
278 }
279
280 void Window::OnWindowEnterHtmlFullScreen() {
281   Emit("enter-html-full-screen");
282 }
283
284 void Window::OnWindowLeaveHtmlFullScreen() {
285   Emit("leave-html-full-screen");
286 }
287
288 void Window::OnRendererUnresponsive() {
289   Emit("unresponsive");
290 }
291
292 void Window::OnRendererResponsive() {
293   Emit("responsive");
294 }
295
296 void Window::OnExecuteWindowsCommand(const std::string& command_name) {
297   Emit("app-command", command_name);
298 }
299
300 void Window::OnTouchBarItemResult(const std::string& item_id,
301                                   const base::DictionaryValue& details) {
302   Emit("-touch-bar-interaction", item_id, details);
303 }
304
305 #if defined(OS_WIN)
306 void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
307   if (IsWindowMessageHooked(message)) {
308     messages_callback_map_[message].Run(
309         ToBuffer(isolate(), static_cast<void*>(&w_param), sizeof(WPARAM)),
310         ToBuffer(isolate(), static_cast<void*>(&l_param), sizeof(LPARAM)));
311   }
312 }
313 #endif
314
315 #if defined(OS_TIZEN)
316 void Window::OnSuspend() {
317   Emit("app-on-suspend");
318 }
319
320 void Window::OnResume() {
321   Emit("app-on-resume");
322 }
323
324 void Window::OnAppControl() {
325   Emit("app-on-appcontrol");
326 }
327 #endif
328
329 // static
330 mate::WrappableBase* Window::New(mate::Arguments* args) {
331   if (!Browser::Get()->is_ready()) {
332     args->ThrowError("Cannot create BrowserWindow before app is ready");
333     return nullptr;
334   }
335
336   if (args->Length() > 1) {
337     args->ThrowError();
338     return nullptr;
339   }
340
341   mate::Dictionary options;
342   if (!(args->Length() == 1 && args->GetNext(&options))) {
343     options = mate::Dictionary::CreateEmpty(args->isolate());
344   }
345
346   return new Window(args->isolate(), args->GetThis(), options);
347 }
348
349 void Window::Close() {
350   window_->Close();
351 }
352
353 void Window::Focus() {
354   window_->Focus(true);
355 }
356
357 void Window::Blur() {
358   window_->Focus(false);
359 }
360
361 bool Window::IsFocused() {
362   return window_->IsFocused();
363 }
364
365 void Window::Show() {
366   window_->Show();
367 }
368
369 void Window::ShowInactive() {
370   // This method doesn't make sense for modal window..
371   if (IsModal())
372     return;
373
374   window_->ShowInactive();
375 }
376
377 void Window::Hide() {
378   window_->Hide();
379 }
380
381 bool Window::IsVisible() {
382   return window_->IsVisible();
383 }
384
385 bool Window::IsEnabled() {
386   return window_->IsEnabled();
387 }
388
389 void Window::Maximize() {
390   window_->Maximize();
391 }
392
393 void Window::Unmaximize() {
394   window_->Unmaximize();
395 }
396
397 bool Window::IsMaximized() {
398   return window_->IsMaximized();
399 }
400
401 void Window::Minimize() {
402   window_->Minimize();
403 }
404
405 void Window::Restore() {
406   window_->Restore();
407 }
408
409 bool Window::IsMinimized() {
410   return window_->IsMinimized();
411 }
412
413 void Window::SetFullScreen(bool fullscreen) {
414   window_->SetFullScreen(fullscreen);
415 }
416
417 bool Window::IsFullscreen() {
418   return window_->IsFullscreen();
419 }
420
421 void Window::SetBounds(const gfx::Rect& bounds, mate::Arguments* args) {
422   bool animate = false;
423   args->GetNext(&animate);
424   window_->SetBounds(bounds, animate);
425 }
426
427 gfx::Rect Window::GetBounds() {
428   return window_->GetBounds();
429 }
430
431 void Window::SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args) {
432   bool animate = false;
433   args->GetNext(&animate);
434   window_->SetContentBounds(bounds, animate);
435 }
436
437 gfx::Rect Window::GetContentBounds() {
438   return window_->GetContentBounds();
439 }
440
441 void Window::SetSize(int width, int height, mate::Arguments* args) {
442   bool animate = false;
443   args->GetNext(&animate);
444   window_->SetSize(gfx::Size(width, height), animate);
445 }
446
447 std::vector<int> Window::GetSize() {
448   std::vector<int> result(2);
449   gfx::Size size = window_->GetSize();
450   result[0] = size.width();
451   result[1] = size.height();
452   return result;
453 }
454
455 void Window::SetContentSize(int width, int height, mate::Arguments* args) {
456   bool animate = false;
457   args->GetNext(&animate);
458   window_->SetContentSize(gfx::Size(width, height), animate);
459 }
460
461 std::vector<int> Window::GetContentSize() {
462   std::vector<int> result(2);
463   gfx::Size size = window_->GetContentSize();
464   result[0] = size.width();
465   result[1] = size.height();
466   return result;
467 }
468
469 void Window::SetMinimumSize(int width, int height) {
470   window_->SetMinimumSize(gfx::Size(width, height));
471 }
472
473 std::vector<int> Window::GetMinimumSize() {
474   std::vector<int> result(2);
475   gfx::Size size = window_->GetMinimumSize();
476   result[0] = size.width();
477   result[1] = size.height();
478   return result;
479 }
480
481 void Window::SetMaximumSize(int width, int height) {
482   window_->SetMaximumSize(gfx::Size(width, height));
483 }
484
485 std::vector<int> Window::GetMaximumSize() {
486   std::vector<int> result(2);
487   gfx::Size size = window_->GetMaximumSize();
488   result[0] = size.width();
489   result[1] = size.height();
490   return result;
491 }
492
493 void Window::SetSheetOffset(double offsetY, mate::Arguments* args) {
494   double offsetX = 0.0;
495   args->GetNext(&offsetX);
496   window_->SetSheetOffset(offsetX, offsetY);
497 }
498
499 void Window::SetResizable(bool resizable) {
500   window_->SetResizable(resizable);
501 }
502
503 bool Window::IsResizable() {
504   return window_->IsResizable();
505 }
506
507 void Window::SetMovable(bool movable) {
508   window_->SetMovable(movable);
509 }
510
511 bool Window::IsMovable() {
512   return window_->IsMovable();
513 }
514
515 void Window::SetMinimizable(bool minimizable) {
516   window_->SetMinimizable(minimizable);
517 }
518
519 bool Window::IsMinimizable() {
520   return window_->IsMinimizable();
521 }
522
523 void Window::SetMaximizable(bool maximizable) {
524   window_->SetMaximizable(maximizable);
525 }
526
527 bool Window::IsMaximizable() {
528   return window_->IsMaximizable();
529 }
530
531 void Window::SetFullScreenable(bool fullscreenable) {
532   window_->SetFullScreenable(fullscreenable);
533 }
534
535 bool Window::IsFullScreenable() {
536   return window_->IsFullScreenable();
537 }
538
539 void Window::SetClosable(bool closable) {
540   window_->SetClosable(closable);
541 }
542
543 bool Window::IsClosable() {
544   return window_->IsClosable();
545 }
546
547 void Window::SetAlwaysOnTop(bool top, mate::Arguments* args) {
548   std::string level = "floating";
549   int relativeLevel = 0;
550   std::string error;
551
552   args->GetNext(&level);
553   args->GetNext(&relativeLevel);
554
555   window_->SetAlwaysOnTop(top, level, relativeLevel, &error);
556
557   if (!error.empty()) {
558     args->ThrowError(error);
559   }
560 }
561
562 bool Window::IsAlwaysOnTop() {
563   return window_->IsAlwaysOnTop();
564 }
565
566 void Window::Center() {
567   window_->Center();
568 }
569
570 void Window::SetPosition(int x, int y, mate::Arguments* args) {
571   bool animate = false;
572   args->GetNext(&animate);
573   window_->SetPosition(gfx::Point(x, y), animate);
574 }
575
576 std::vector<int> Window::GetPosition() {
577   std::vector<int> result(2);
578   gfx::Point pos = window_->GetPosition();
579   result[0] = pos.x();
580   result[1] = pos.y();
581   return result;
582 }
583
584 void Window::SetTitle(const std::string& title) {
585   window_->SetTitle(title);
586 }
587
588 std::string Window::GetTitle() {
589   return window_->GetTitle();
590 }
591
592 void Window::FlashFrame(bool flash) {
593   window_->FlashFrame(flash);
594 }
595
596 void Window::SetSkipTaskbar(bool skip) {
597   window_->SetSkipTaskbar(skip);
598 }
599
600 void Window::SetKiosk(bool kiosk) {
601   window_->SetKiosk(kiosk);
602 }
603
604 bool Window::IsKiosk() {
605   return window_->IsKiosk();
606 }
607
608 void Window::SetBackgroundColor(const std::string& color_name) {
609   window_->SetBackgroundColor(color_name);
610 }
611
612 void Window::SetHasShadow(bool has_shadow) {
613   window_->SetHasShadow(has_shadow);
614 }
615
616 bool Window::HasShadow() {
617   return window_->HasShadow();
618 }
619
620 void Window::FocusOnWebView() {
621   window_->FocusOnWebView();
622 }
623
624 void Window::BlurWebView() {
625   window_->BlurWebView();
626 }
627
628 bool Window::IsWebViewFocused() {
629   return window_->IsWebViewFocused();
630 }
631
632 void Window::SetRepresentedFilename(const std::string& filename) {
633   window_->SetRepresentedFilename(filename);
634 }
635
636 std::string Window::GetRepresentedFilename() {
637   return window_->GetRepresentedFilename();
638 }
639
640 void Window::SetDocumentEdited(bool edited) {
641   window_->SetDocumentEdited(edited);
642 }
643
644 bool Window::IsDocumentEdited() {
645   return window_->IsDocumentEdited();
646 }
647
648 void Window::SetIgnoreMouseEvents(bool ignore) {
649   return window_->SetIgnoreMouseEvents(ignore);
650 }
651
652 void Window::SetContentProtection(bool enable) {
653   return window_->SetContentProtection(enable);
654 }
655
656 void Window::SetFocusable(bool focusable) {
657   return window_->SetFocusable(focusable);
658 }
659
660 void Window::SetProgressBar(double progress, mate::Arguments* args) {
661   mate::Dictionary options;
662   std::string mode;
663   NativeWindow::ProgressState state = NativeWindow::PROGRESS_NORMAL;
664
665   args->GetNext(&options) && options.Get("mode", &mode);
666
667   if (mode == "error") {
668     state = NativeWindow::PROGRESS_ERROR;
669   } else if (mode == "paused") {
670     state = NativeWindow::PROGRESS_PAUSED;
671   } else if (mode == "indeterminate") {
672     state = NativeWindow::PROGRESS_INDETERMINATE;
673   } else if (mode == "none") {
674     state = NativeWindow::PROGRESS_NONE;
675   }
676
677   window_->SetProgressBar(progress, state);
678 }
679
680 void Window::SetOverlayIcon(const gfx::Image& overlay,
681                             const std::string& description) {
682   window_->SetOverlayIcon(overlay, description);
683 }
684
685 bool Window::SetThumbarButtons(mate::Arguments* args) {
686 #if defined(OS_WIN)
687   std::vector<TaskbarHost::ThumbarButton> buttons;
688   if (!args->GetNext(&buttons)) {
689     args->ThrowError();
690     return false;
691   }
692   auto window = static_cast<NativeWindowViews*>(window_.get());
693   return window->taskbar_host().SetThumbarButtons(
694       window_->GetAcceleratedWidget(), buttons);
695 #else
696   return false;
697 #endif
698 }
699
700 void Window::SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> value) {
701   mate::Handle<Menu> menu;
702   if (value->IsObject() &&
703       mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" &&
704       mate::ConvertFromV8(isolate, value, &menu)) {
705     menu_.Reset(isolate, menu.ToV8());
706     window_->SetMenu(menu->model());
707   } else if (value->IsNull()) {
708     menu_.Reset();
709     window_->SetMenu(nullptr);
710   } else {
711     isolate->ThrowException(v8::Exception::TypeError(
712         mate::StringToV8(isolate, "Invalid Menu")));
713   }
714 }
715
716 void Window::SetAutoHideMenuBar(bool auto_hide) {
717   window_->SetAutoHideMenuBar(auto_hide);
718 }
719
720 bool Window::IsMenuBarAutoHide() {
721   return window_->IsMenuBarAutoHide();
722 }
723
724 void Window::SetMenuBarVisibility(bool visible) {
725   window_->SetMenuBarVisibility(visible);
726 }
727
728 bool Window::IsMenuBarVisible() {
729   return window_->IsMenuBarVisible();
730 }
731
732 #if defined(OS_WIN)
733 bool Window::HookWindowMessage(UINT message,
734                                const MessageCallback& callback) {
735   messages_callback_map_[message] = callback;
736   return true;
737 }
738
739 void Window::UnhookWindowMessage(UINT message) {
740   if (!ContainsKey(messages_callback_map_, message))
741     return;
742
743   messages_callback_map_.erase(message);
744 }
745
746 bool Window::IsWindowMessageHooked(UINT message) {
747   return ContainsKey(messages_callback_map_, message);
748 }
749
750 void Window::UnhookAllWindowMessages() {
751   messages_callback_map_.clear();
752 }
753
754 bool Window::SetThumbnailClip(const gfx::Rect& region) {
755   auto window = static_cast<NativeWindowViews*>(window_.get());
756   return window->taskbar_host().SetThumbnailClip(
757       window_->GetAcceleratedWidget(), region);
758 }
759
760 bool Window::SetThumbnailToolTip(const std::string& tooltip) {
761   auto window = static_cast<NativeWindowViews*>(window_.get());
762   return window->taskbar_host().SetThumbnailToolTip(
763       window_->GetAcceleratedWidget(), tooltip);
764 }
765
766 void Window::SetAppDetails(const mate::Dictionary& options) {
767   base::string16 app_id;
768   base::FilePath app_icon_path;
769   int app_icon_index = 0;
770   base::string16 relaunch_command;
771   base::string16 relaunch_display_name;
772
773   options.Get("appId", &app_id);
774   options.Get("appIconPath", &app_icon_path);
775   options.Get("appIconIndex", &app_icon_index);
776   options.Get("relaunchCommand", &relaunch_command);
777   options.Get("relaunchDisplayName", &relaunch_display_name);
778
779   ui::win::SetAppDetailsForWindow(
780       app_id, app_icon_path, app_icon_index,
781       relaunch_command, relaunch_display_name,
782       window_->GetAcceleratedWidget());
783 }
784 #endif
785
786 #if defined(TOOLKIT_VIEWS)
787 void Window::SetIcon(mate::Handle<NativeImage> icon) {
788 #if defined(OS_WIN)
789   static_cast<NativeWindowViews*>(window_.get())->SetIcon(
790       icon->GetHICON(GetSystemMetrics(SM_CXSMICON)),
791       icon->GetHICON(GetSystemMetrics(SM_CXICON)));
792 #elif defined(USE_X11)
793   static_cast<NativeWindowViews*>(window_.get())->SetIcon(
794       icon->image().AsImageSkia());
795 #endif
796 }
797 #endif
798
799 void Window::SetAspectRatio(double aspect_ratio, mate::Arguments* args) {
800   gfx::Size extra_size;
801   args->GetNext(&extra_size);
802   window_->SetAspectRatio(aspect_ratio, extra_size);
803 }
804
805 void Window::PreviewFile(const std::string& path, mate::Arguments* args) {
806   std::string display_name;
807   if (!args->GetNext(&display_name))
808     display_name = path;
809   window_->PreviewFile(path, display_name);
810 }
811
812 void Window::CloseFilePreview() {
813   window_->CloseFilePreview();
814 }
815
816 void Window::SetParentWindow(v8::Local<v8::Value> value,
817                              mate::Arguments* args) {
818   if (IsModal()) {
819     args->ThrowError("Can not be called for modal window");
820     return;
821   }
822
823   mate::Handle<Window> parent;
824   if (value->IsNull()) {
825     RemoveFromParentChildWindows();
826     parent_window_.Reset();
827     window_->SetParentWindow(nullptr);
828   } else if (mate::ConvertFromV8(isolate(), value, &parent)) {
829     parent_window_.Reset(isolate(), value);
830     window_->SetParentWindow(parent->window_.get());
831     parent->child_windows_.Set(isolate(), ID(), GetWrapper());
832   } else {
833     args->ThrowError("Must pass BrowserWindow instance or null");
834   }
835 }
836
837 v8::Local<v8::Value> Window::GetParentWindow() const {
838   if (parent_window_.IsEmpty())
839     return v8::Null(isolate());
840   else
841     return v8::Local<v8::Value>::New(isolate(), parent_window_);
842 }
843
844 std::vector<v8::Local<v8::Object>> Window::GetChildWindows() const {
845   return child_windows_.Values(isolate());
846 }
847
848 v8::Local<v8::Value> Window::GetBrowserView() const {
849   if (browser_view_.IsEmpty()) {
850     return v8::Null(isolate());
851   }
852
853   return v8::Local<v8::Value>::New(isolate(), browser_view_);
854 }
855
856 void Window::SetBrowserView(v8::Local<v8::Value> value) {
857   mate::Handle<BrowserView> browser_view;
858   if (value->IsNull()) {
859     window_->SetBrowserView(nullptr);
860     browser_view_.Reset();
861   } else if (mate::ConvertFromV8(isolate(), value, &browser_view)) {
862     window_->SetBrowserView(browser_view->view());
863     browser_view_.Reset(isolate(), value);
864   }
865 }
866
867 bool Window::IsModal() const {
868   return window_->is_modal();
869 }
870
871 v8::Local<v8::Value> Window::GetNativeWindowHandle() {
872   gfx::AcceleratedWidget handle = window_->GetAcceleratedWidget();
873   return ToBuffer(
874       isolate(), static_cast<void*>(&handle), sizeof(gfx::AcceleratedWidget));
875 }
876
877 void Window::SetVisibleOnAllWorkspaces(bool visible) {
878   return window_->SetVisibleOnAllWorkspaces(visible);
879 }
880
881 bool Window::IsVisibleOnAllWorkspaces() {
882   return window_->IsVisibleOnAllWorkspaces();
883 }
884
885 void Window::SetAutoHideCursor(bool auto_hide) {
886   window_->SetAutoHideCursor(auto_hide);
887 }
888
889 void Window::SetVibrancy(mate::Arguments* args) {
890   std::string type;
891
892   args->GetNext(&type);
893   window_->SetVibrancy(type);
894 }
895
896 void Window::SetTouchBar(const std::vector<mate::PersistentDictionary>& items) {
897   window_->SetTouchBar(items);
898 }
899
900 void Window::RefreshTouchBarItem(const std::string& item_id) {
901   window_->RefreshTouchBarItem(item_id);
902 }
903
904 void Window::SetEscapeTouchBarItem(const mate::PersistentDictionary& item) {
905   window_->SetEscapeTouchBarItem(item);
906 }
907
908 int32_t Window::ID() const {
909   return weak_map_id();
910 }
911
912 v8::Local<v8::Value> Window::WebContents(v8::Isolate* isolate) {
913   if (web_contents_.IsEmpty()) {
914     return v8::Null(isolate);
915   }
916
917   return v8::Local<v8::Value>::New(isolate, web_contents_);
918 }
919
920 void Window::RemoveFromParentChildWindows() {
921   if (parent_window_.IsEmpty())
922     return;
923
924   mate::Handle<Window> parent;
925   if (!mate::ConvertFromV8(isolate(), GetParentWindow(), &parent))
926     return;
927
928   parent->child_windows_.Remove(ID());
929 }
930
931 // static
932 void Window::BuildPrototype(v8::Isolate* isolate,
933                             v8::Local<v8::FunctionTemplate> prototype) {
934   prototype->SetClassName(mate::StringToV8(isolate, "BrowserWindow"));
935   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
936       .MakeDestroyable()
937       .SetMethod("close", &Window::Close)
938       .SetMethod("focus", &Window::Focus)
939       .SetMethod("blur", &Window::Blur)
940       .SetMethod("isFocused", &Window::IsFocused)
941       .SetMethod("show", &Window::Show)
942       .SetMethod("showInactive", &Window::ShowInactive)
943       .SetMethod("hide", &Window::Hide)
944       .SetMethod("isVisible", &Window::IsVisible)
945       .SetMethod("isEnabled", &Window::IsEnabled)
946       .SetMethod("maximize", &Window::Maximize)
947       .SetMethod("unmaximize", &Window::Unmaximize)
948       .SetMethod("isMaximized", &Window::IsMaximized)
949       .SetMethod("minimize", &Window::Minimize)
950       .SetMethod("restore", &Window::Restore)
951       .SetMethod("isMinimized", &Window::IsMinimized)
952       .SetMethod("setFullScreen", &Window::SetFullScreen)
953       .SetMethod("isFullScreen", &Window::IsFullscreen)
954       .SetMethod("setAspectRatio", &Window::SetAspectRatio)
955       .SetMethod("previewFile", &Window::PreviewFile)
956       .SetMethod("closeFilePreview", &Window::CloseFilePreview)
957 #if !defined(OS_WIN)
958       .SetMethod("setParentWindow", &Window::SetParentWindow)
959 #endif
960       .SetMethod("getParentWindow", &Window::GetParentWindow)
961       .SetMethod("getChildWindows", &Window::GetChildWindows)
962       .SetMethod("getBrowserView", &Window::GetBrowserView)
963       .SetMethod("setBrowserView", &Window::SetBrowserView)
964       .SetMethod("isModal", &Window::IsModal)
965       .SetMethod("getNativeWindowHandle", &Window::GetNativeWindowHandle)
966       .SetMethod("getBounds", &Window::GetBounds)
967       .SetMethod("setBounds", &Window::SetBounds)
968       .SetMethod("getSize", &Window::GetSize)
969       .SetMethod("setSize", &Window::SetSize)
970       .SetMethod("getContentBounds", &Window::GetContentBounds)
971       .SetMethod("setContentBounds", &Window::SetContentBounds)
972       .SetMethod("getContentSize", &Window::GetContentSize)
973       .SetMethod("setContentSize", &Window::SetContentSize)
974       .SetMethod("setMinimumSize", &Window::SetMinimumSize)
975       .SetMethod("getMinimumSize", &Window::GetMinimumSize)
976       .SetMethod("setMaximumSize", &Window::SetMaximumSize)
977       .SetMethod("getMaximumSize", &Window::GetMaximumSize)
978       .SetMethod("setSheetOffset", &Window::SetSheetOffset)
979       .SetMethod("setResizable", &Window::SetResizable)
980       .SetMethod("isResizable", &Window::IsResizable)
981       .SetMethod("setMovable", &Window::SetMovable)
982       .SetMethod("isMovable", &Window::IsMovable)
983       .SetMethod("setMinimizable", &Window::SetMinimizable)
984       .SetMethod("isMinimizable", &Window::IsMinimizable)
985       .SetMethod("setMaximizable", &Window::SetMaximizable)
986       .SetMethod("isMaximizable", &Window::IsMaximizable)
987       .SetMethod("setFullScreenable", &Window::SetFullScreenable)
988       .SetMethod("isFullScreenable", &Window::IsFullScreenable)
989       .SetMethod("setClosable", &Window::SetClosable)
990       .SetMethod("isClosable", &Window::IsClosable)
991       .SetMethod("setAlwaysOnTop", &Window::SetAlwaysOnTop)
992       .SetMethod("isAlwaysOnTop", &Window::IsAlwaysOnTop)
993       .SetMethod("center", &Window::Center)
994       .SetMethod("setPosition", &Window::SetPosition)
995       .SetMethod("getPosition", &Window::GetPosition)
996       .SetMethod("setTitle", &Window::SetTitle)
997       .SetMethod("getTitle", &Window::GetTitle)
998       .SetMethod("flashFrame", &Window::FlashFrame)
999       .SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar)
1000       .SetMethod("setKiosk", &Window::SetKiosk)
1001       .SetMethod("isKiosk", &Window::IsKiosk)
1002       .SetMethod("setBackgroundColor", &Window::SetBackgroundColor)
1003       .SetMethod("setHasShadow", &Window::SetHasShadow)
1004       .SetMethod("hasShadow", &Window::HasShadow)
1005       .SetMethod("setRepresentedFilename", &Window::SetRepresentedFilename)
1006       .SetMethod("getRepresentedFilename", &Window::GetRepresentedFilename)
1007       .SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
1008       .SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
1009       .SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
1010       .SetMethod("setContentProtection", &Window::SetContentProtection)
1011       .SetMethod("setFocusable", &Window::SetFocusable)
1012       .SetMethod("focusOnWebView", &Window::FocusOnWebView)
1013       .SetMethod("blurWebView", &Window::BlurWebView)
1014       .SetMethod("isWebViewFocused", &Window::IsWebViewFocused)
1015       .SetMethod("setProgressBar", &Window::SetProgressBar)
1016       .SetMethod("setOverlayIcon", &Window::SetOverlayIcon)
1017       .SetMethod("setThumbarButtons", &Window::SetThumbarButtons)
1018       .SetMethod("setMenu", &Window::SetMenu)
1019       .SetMethod("setAutoHideMenuBar", &Window::SetAutoHideMenuBar)
1020       .SetMethod("isMenuBarAutoHide", &Window::IsMenuBarAutoHide)
1021       .SetMethod("setMenuBarVisibility", &Window::SetMenuBarVisibility)
1022       .SetMethod("isMenuBarVisible", &Window::IsMenuBarVisible)
1023       .SetMethod("setVisibleOnAllWorkspaces",
1024                  &Window::SetVisibleOnAllWorkspaces)
1025       .SetMethod("isVisibleOnAllWorkspaces",
1026                  &Window::IsVisibleOnAllWorkspaces)
1027 #if defined(OS_MACOSX)
1028       .SetMethod("setAutoHideCursor", &Window::SetAutoHideCursor)
1029 #endif
1030       .SetMethod("setVibrancy", &Window::SetVibrancy)
1031       .SetMethod("_setTouchBarItems", &Window::SetTouchBar)
1032       .SetMethod("_refreshTouchBarItem", &Window::RefreshTouchBarItem)
1033       .SetMethod("_setEscapeTouchBarItem", &Window::SetEscapeTouchBarItem)
1034 #if defined(OS_WIN)
1035       .SetMethod("hookWindowMessage", &Window::HookWindowMessage)
1036       .SetMethod("isWindowMessageHooked", &Window::IsWindowMessageHooked)
1037       .SetMethod("unhookWindowMessage", &Window::UnhookWindowMessage)
1038       .SetMethod("unhookAllWindowMessages", &Window::UnhookAllWindowMessages)
1039       .SetMethod("setThumbnailClip", &Window::SetThumbnailClip)
1040       .SetMethod("setThumbnailToolTip", &Window::SetThumbnailToolTip)
1041       .SetMethod("setAppDetails", &Window::SetAppDetails)
1042 #endif
1043 #if defined(TOOLKIT_VIEWS)
1044       .SetMethod("setIcon", &Window::SetIcon)
1045 #endif
1046       .SetProperty("id", &Window::ID)
1047       .SetProperty("webContents", &Window::WebContents);
1048 }
1049
1050 // static
1051 v8::Local<v8::Value> Window::From(v8::Isolate* isolate,
1052                                   NativeWindow* native_window) {
1053   auto existing = TrackableObject::FromWrappedClass(isolate, native_window);
1054   if (existing)
1055     return existing->GetWrapper();
1056   else
1057     return v8::Null(isolate);
1058 }
1059
1060 }  // namespace api
1061
1062 }  // namespace atom
1063
1064
1065 namespace {
1066
1067 using atom::api::Window;
1068
1069 void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
1070                 v8::Local<v8::Context> context, void* priv) {
1071   v8::Isolate* isolate = context->GetIsolate();
1072   Window::SetConstructor(isolate, base::Bind(&Window::New));
1073
1074   mate::Dictionary browser_window(
1075       isolate, Window::GetConstructor(isolate)->GetFunction());
1076   browser_window.SetMethod("fromId",
1077                            &mate::TrackableObject<Window>::FromWeakMapID);
1078   browser_window.SetMethod("getAllWindows",
1079                            &mate::TrackableObject<Window>::GetAll);
1080
1081   mate::Dictionary dict(isolate, exports);
1082   dict.Set("BrowserWindow", browser_window);
1083 }
1084
1085 }  // namespace
1086
1087 NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_browser_window, Initialize)