diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 5410345ab56c..af402de07765 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -584,8 +584,12 @@ void Window::SetFocusable(bool focusable) { return window_->SetFocusable(focusable); } -void Window::SetProgressBar(double progress) { - window_->SetProgressBar(progress); +void Window::SetProgressBar(double progress, mate::Arguments* args) { + mate::Dictionary options; + std::string mode; + args->GetNext(&options) && options.Get("mode", &mode); + + window_->SetProgressBar(progress, mode); } void Window::SetOverlayIcon(const gfx::Image& overlay, diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index e9aeaac0cde2..7c649793948f 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -155,7 +155,7 @@ class Window : public mate::TrackableObject, void SetIgnoreMouseEvents(bool ignore); void SetContentProtection(bool enable); void SetFocusable(bool focusable); - void SetProgressBar(double progress); + void SetProgressBar(double progress, mate::Arguments* args); void SetOverlayIcon(const gfx::Image& overlay, const std::string& description); bool SetThumbarButtons(mate::Arguments* args); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 352297223f2e..974daf8d3b69 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -143,7 +143,8 @@ class NativeWindow : public base::SupportsUserData, virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; // Taskbar/Dock APIs. - virtual void SetProgressBar(double progress) = 0; + virtual void SetProgressBar(double progress, + const std::string& mode) = 0; virtual void SetOverlayIcon(const gfx::Image& overlay, const std::string& description) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 5f948ddf6793..1a04ff9a494c 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -85,7 +85,7 @@ class NativeWindowMac : public NativeWindow, void SetParentWindow(NativeWindow* parent) override; gfx::NativeWindow GetNativeWindow() override; gfx::AcceleratedWidget GetAcceleratedWidget() override; - void SetProgressBar(double progress) override; + void SetProgressBar(double progress, const std::string& mode) override; void SetOverlayIcon(const gfx::Image& overlay, const std::string& description) override; void SetVisibleOnAllWorkspaces(bool visible) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 98e8b7c36dc1..8e8f988ee99c 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -979,7 +979,7 @@ gfx::AcceleratedWidget NativeWindowMac::GetAcceleratedWidget() { return inspectable_web_contents()->GetView()->GetNativeView(); } -void NativeWindowMac::SetProgressBar(double progress) { +void NativeWindowMac::SetProgressBar(double progress, const std::string& mode) { NSDockTile* dock_tile = [NSApp dockTile]; // For the first time API invoked, we need to create a ContentView in DockTile. diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 52e643f3589e..39e402aba53e 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -904,9 +904,10 @@ gfx::NativeWindow NativeWindowViews::GetNativeWindow() { return window_->GetNativeWindow(); } -void NativeWindowViews::SetProgressBar(double progress) { +void NativeWindowViews::SetProgressBar( + double progress, const std::string& mode) { #if defined(OS_WIN) - taskbar_host_.SetProgressBar(GetAcceleratedWidget(), progress); + taskbar_host_.SetProgressBar(GetAcceleratedWidget(), progress, mode); #elif defined(USE_X11) if (unity::IsRunning()) { unity::SetProgressFraction(progress); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 51b00e8831fd..82c260aeb5b8 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -104,7 +104,7 @@ class NativeWindowViews : public NativeWindow, gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, const std::string& description) override; - void SetProgressBar(double value) override; + void SetProgressBar(double value, const std::string& mode) override; void SetAutoHideMenuBar(bool auto_hide) override; bool IsMenuBarAutoHide() override; void SetMenuBarVisibility(bool visible) override; diff --git a/atom/browser/ui/win/taskbar_host.cc b/atom/browser/ui/win/taskbar_host.cc index adc41cf1fb9d..a9ff16dccaed 100644 --- a/atom/browser/ui/win/taskbar_host.cc +++ b/atom/browser/ui/win/taskbar_host.cc @@ -117,18 +117,40 @@ bool TaskbarHost::SetThumbarButtons( return SUCCEEDED(r); } -bool TaskbarHost::SetProgressBar(HWND window, double value) { +bool TaskbarHost::SetProgressBar( + HWND window, double value, const std::string& mode) { if (!InitializeTaskbar()) return false; - HRESULT r; - if (value > 1.0) - r = taskbar_->SetProgressState(window, TBPF_INDETERMINATE); - else if (value < 0) - r = taskbar_->SetProgressState(window, TBPF_NOPROGRESS); - else - r = taskbar_->SetProgressValue(window, static_cast(value * 100), 100); - return SUCCEEDED(r); + HRESULT barR; + HRESULT stateR; + + if (value > 1.0 || mode == "indeterminate") { + barR = taskbar_->SetProgressState(window, TBPF_INDETERMINATE); + } else if (value < 0 || mode == "none") { + barR = taskbar_->SetProgressState(window, TBPF_NOPROGRESS); + } else { + // Unless SetProgressState set a blocking state (TBPF_ERROR, TBPF_PAUSED) + // for the window, a call to SetProgressValue assumes the TBPF_NORMAL + // state even if it is not explicitly set. + // SetProgressValue overrides and clears the TBPF_INDETERMINATE state. + if (mode == "error") { + stateR = taskbar_->SetProgressState(window, TBPF_ERROR); + } else if (mode == "paused") { + stateR = taskbar_->SetProgressState(window, TBPF_PAUSED); + } else { + stateR = taskbar_->SetProgressState(window, TBPF_NORMAL); + } + + if (SUCCEEDED(stateR)) { + int val = static_cast(value * 100); + barR = taskbar_->SetProgressValue(window, val, 100); + } else { + return SUCCEEDED(stateR); + } + } + + return SUCCEEDED(barR); } bool TaskbarHost::SetOverlayIcon( diff --git a/atom/browser/ui/win/taskbar_host.h b/atom/browser/ui/win/taskbar_host.h index fb87ab4a6944..c76340cd6efe 100644 --- a/atom/browser/ui/win/taskbar_host.h +++ b/atom/browser/ui/win/taskbar_host.h @@ -35,7 +35,7 @@ class TaskbarHost { HWND window, const std::vector& buttons); // Set the progress state in taskbar. - bool SetProgressBar(HWND window, double value); + bool SetProgressBar(HWND window, double value, const std::string& mode); // Set the overlay icon in taskbar. bool SetOverlayIcon( diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index a4d149b2bcd6..d0c21ecd491e 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -956,9 +956,11 @@ Same as `webContents.reload`. Sets the `menu` as the window's menu bar, setting it to `null` will remove the menu bar. -#### `win.setProgressBar(progress)` +#### `win.setProgressBar(progress[, options])` * `progress` Double +* `options` Object (optional) + * `mode` String _Windows_ - Mode for the progres bar (`none`, `normal`, `indeterminate`, `error`, or `paused`) Sets progress value in progress bar. Valid range is [0, 1.0]. @@ -969,6 +971,10 @@ On Linux platform, only supports Unity desktop environment, you need to specify the `*.desktop` file name to `desktopName` field in `package.json`. By default, it will assume `app.getName().desktop`. +On Windows, a mode can be passed. Accepted values are `none`, `normal`, +`indeterminate`, `error`, and `paused`. If you call `setProgressBar` without a +mode set (but with a value within the valid range), `normal` will be assumed. + #### `win.setOverlayIcon(overlay, description)` _Windows_ * `overlay` [NativeImage](native-image.md) - the icon to display on the bottom diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 362105c7bb15..39299eeae1bc 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -391,6 +391,24 @@ describe('browser-window module', function () { w.setProgressBar(-1) }) }) + + it('sets the progress using "paused" mode', function () { + assert.doesNotThrow(function () { + w.setProgressBar(0.5, {mode: 'paused'}) + }) + }) + + it('sets the progress using "error" mode', function () { + assert.doesNotThrow(function () { + w.setProgressBar(0.5, {mode: 'error'}) + }) + }) + + it('sets the progress using "normal" mode', function () { + assert.doesNotThrow(function () { + w.setProgressBar(0.5, {mode: 'normal'}) + }) + }) }) describe('BrowserWindow.fromId(id)', function () {