-
Notifications
You must be signed in to change notification settings - Fork 15.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Notifications from the main process #9269
Conversation
atom/browser/ui/win/toast_lib.cc
Outdated
|
||
inline HRESULT initialize() { | ||
HINSTANCE LibShell32 = LoadLibrary(L"SHELL32.DLL"); | ||
HRESULT hr = loadFunctionFromLibrary(LibShell32, "SetCurrentProcessExplicitAppUserModelID", SetCurrentProcessExplicitAppUserModelID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This strikes me as potentially dangerous... is that something we really want to call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@felixrieseberg Hmm, now that I think about it maybe not. app.setUserModelID
probably handles this for us, will test on Windows 8 (where appUserModelID is strictly required)
👏 A+ effort, thanks a ton! We should make sure that the behavior between renderer and main process is identical - for Windows, that would mean that the notifications here use the brand new Windows 7 notifications. |
Ah yes, forgot about those 😆 Will add it to the list 😄 |
Instead of reimplementing windows 7 notifications I just called the Also of note here, is if the Notification initialization fails on W8 or W10 we fall back to the W7 notification implementation so there will always be a Notification implementation ready to go 👍 |
I pushed up core linux support, if I could get some assistance from someone getting the click event working (I couldn't make it play ball) that would be great. /cc @electron/maintainers |
This is ready for 👀 @electron/maintainers |
c681233
to
aecfa31
Compare
4208b55
to
d1fc832
Compare
Pinged MS folks who may also want to make notifications 👍 👍 |
@MarshallOfSound How about using A few features like Or is there anything preventing you from reusing the code? |
@zcbenz That's what I initially tried to do, but something (and now I can't remember what) kept crashing 😢 I can go back to trying to use the |
@MarshallOfSound I think we should try reusing |
@zcbenz Implementation updated to use |
@@ -5,7 +5,9 @@ to the user. Electron conveniently allows developers to send notifications with | |||
the [HTML5 Notification API](https://notifications.spec.whatwg.org/), using | |||
the currently running operating system's native notification APIs to display it. | |||
|
|||
**Note:** Since this is an HTML5 API it is only available in the renderer process. | |||
**Note:** Since this is an HTML5 API it is only available in the renderer process. If | |||
you want to show Notifications in the main process please check out the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is not really "show in main process", but more like "Invoke/create notification from main process" IMO, just my $0.02 😄
brightray/browser/notification.h
Outdated
@@ -26,7 +26,9 @@ class Notification { | |||
const std::string& tag, | |||
const GURL& icon_url, | |||
const SkBitmap& icon, | |||
const bool silent) = 0; | |||
const bool silent, | |||
const bool hasReply, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to add const
, since bool
is passed by value here, also in C++ we use snake_case
for variable names:
bool silent,
bool has_reply,
brightray/browser/notification.h
Outdated
const bool silent) = 0; | ||
const bool silent, | ||
const bool hasReply, | ||
const base::string16 replyPlaceholder) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should pass const reference for strings:
const base::string16& reply_placeholder
@@ -21,15 +21,20 @@ - (instancetype)initWithPresenter:(brightray::NotificationPresenterMac*)presente | |||
- (void)userNotificationCenter:(NSUserNotificationCenter*)center | |||
didDeliverNotification:(NSUserNotification*)notif { | |||
auto notification = presenter_->GetNotification(notif); | |||
if (notification) | |||
if (notification) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a trailing space.
@@ -16,6 +17,9 @@ class NotificationDelegate : public content::DesktopNotificationDelegate { | |||
|
|||
// Failed to send the notification. | |||
virtual void NotificationFailed() {} | |||
|
|||
// Notification was replied to | |||
virtual void NotificationReplied(std::string reply) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should pass const reference here:
NotificationReplied(const std::string& reply)
void Dismiss() override; | ||
|
||
void NotificationDisplayed(); | ||
void NotificationReplied(std::string reply); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should pass const reference here:
NotificationReplied(const std::string& reply)
void NotifyPropsUpdated(); | ||
|
||
private: | ||
base::string16 title_ = base::UTF8ToUTF16(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strings are initialized to "" by default, there is no need to explicitly initialize it here.
Emit("close"); | ||
} | ||
|
||
void Notification::NotifyPropsUpdated() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method seems redundant.
|
||
// Showing notifications | ||
void Notification::Show() { | ||
SkBitmap image = *(new SkBitmap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable is redundant, we can pass icon_.AsBitmap()
to Show(...)
, when icon is empty it will just return an empty bitmap.
auto notif = presenter_->CreateNotification(adapter.get()); | ||
if (notif) { | ||
ignore_result(adapter.release()); // it will release itself automatically. | ||
GURL nullUrl = *(new GURL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is redundant:
notif->Show(..., GURL(), ...);
bool initialized_ = false; | ||
void Notification::OnInitialProps() { | ||
if (!initialized_) { | ||
presenter_ = brightray::NotificationPresenter::Create(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The presenter can be received by calling BrowserClient::GetNotificationPresenter()
.
Also it should be noticed that not every platform supports notifications, so it might return null and this case should be guarded. We also need to add a new API like Notification.isSupported()
to indicate whether notification is supported on current platform.
@zcbenz Updated as per feedback 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woops 😆 Didn't want to leave that in 🤣
+1 interwebs for you sir if this works nicely |
Is there any way I can use this in any other process then main? It would get rid of a dependency in my project and I imagine this looks cleaner. Nice work by the way |
@alexanderepstein which process would that be? You can use it in any main process. And renderer had notifications all along. |
@black-snow So from my index.html I include another javscript file that's not my main.js will I be able to call this by doing something like And then try to use run the notification there? Additionally do these notifications have buttons preferebly more then 1? I have it set up where one is a dismiss button and the other one performs an action |
@alexanderepstein In the renderer process you can use the HTML5 Notification API. new Notification('Hello') This API is purely for the main process |
@alexanderepstein also there usually ain't no buttons in notifications. If you need buttons a dialog is what you want. Of course you could also listen to click/dismiss on a notification. |
@MarshallOfSound Really fantastic work! I found an issue with the icon notifications on windows. It only shows the first icon passed to the Notification module , so concurrent notifications always show the same icon. I tried to look in the code and see if I could spot a simple gap in logic, but I was unable to. |
Thanks for everyone's hard work! What is the status on support for Sticky notifications on macOS? |
This is a WIP of extracting the Notification logic that hooks into the Chromium notification model in the renderer process to a simpler API to use from the main process. It also adds a few extras like inline replies on macOS.
An example of what this API looks like (at least currently on macOS)
Currently just supports macOS and Windows, this is just to get some early implementation feedback 👍
Platform Support Status:
TODO:
Explore Windows 10 inline reply possibilityNot required for the first mergeDuration on platforms that support itNot required for the first mergeSticky (permanent) on platforms that support itNot required for the first mergeFixes #3359
Note: This API is marked as Experimental in the docs 👍