Pavel Koryagin
Pavel Koryagin

Reputation: 1481

Notification window in Mac. With or without Qt

Qt project on Mac OS X. I need to show notification window on top without stealing a focus from any active application.

Here the widget constructor part:

setWindowFlags(
    Qt::FramelessWindowHint |
    Qt::WindowSystemMenuHint |
    Qt::Tool |
    Qt::WindowStaysOnTopHint
);
setAttribute(Qt::WA_TranslucentBackground);

Qt::WA_ShowWithoutActivating doesn't affect anything.

Is there a way to do that? I'm ready to implement the native Carbon/Cocoa solution there, but Qt is preferred. Or maybe I'm wrong in Mac philosophy and I should notify user in a kind another manner?

Update Growl doesn't support editor line in its notifications, does it?

Upvotes: 5

Views: 4104

Answers (5)

krab
krab

Reputation: 101

Ive just tested these flags

Qt::FramelessWindowHint |Qt::WindowSystemMenuHint |Qt::WindowStaysOnTopHint

And

 setFocusPolicy(Qt::NoFocus);
 setAttribute(Qt::WA_ShowWithoutActivating,true); 

Without Cocoa or Carbon code for window flags/masks. And notifyWindow works like on Windows or Linux.

Upvotes: 0

Seven
Seven

Reputation: 223

try this on mac:

setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_AlwaysStackOnTop);

Upvotes: 0

Pavel Koryagin
Pavel Koryagin

Reputation: 1481

I did it!

#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
#endif

NotifyWindow::NotifyWindow() : QWidget(0 /* This zero is the first point */) {

    setWindowFlags(
    #ifdef Q_OS_MAC
        Qt::SubWindow | // This type flag is the second point
    #else
        Qt::Tool |
    #endif
        Qt::FramelessWindowHint |
        Qt::WindowSystemMenuHint |
        Qt::WindowStaysOnTopHint
    );
    setAttribute(Qt::WA_TranslucentBackground);

    // And this conditional block is the third point
#ifdef Q_OS_MAC
    winId(); // This call creates the OS window ID itself.
             // qt_mac_window_for() doesn't

    int setAttr[] = {
        kHIWindowBitDoesNotHide, // Shows window even when app is hidden

        kHIWindowBitDoesNotCycle, // Not sure if required, but not bad

        kHIWindowBitNoShadow, // Keep this if you have your own design
                              // with cross-platform drawn shadows
        0 };
    int clearAttr[] = { 0 };
    HIWindowChangeAttributes(qt_mac_window_for(this), setAttr, clearAttr);
#endif
}

We get almost the same nice behavior as in Windows:

  • It does not stole focus on show. (Two weeks of searching over the Internet)
  • The controls there handle the first user click, while other windows need an extra click to activate.
  • When the window is being activated, the other windows of the same application, do not bubble up to the front.
  • And a small problem remains, but at least it has a simple workaround. Or even could be left.

Upvotes: 6

Daniel A. White
Daniel A. White

Reputation: 190943

You could implement Growl. http://growl.info/documentation/developer/

Upvotes: 0

Avisra
Avisra

Reputation: 740

Pavel,

Have you heard of Growl? Growl is a VERY impressive notification app that you can bundle and use with your application. Adium - a popular instant messaging app for OS X - uses it for all notifications.

http://growl.info/

Upvotes: 4

Related Questions