Changing window titlebar colour in macOS



  • Hi, I would like to change the colour of the window titlebar on OSX/macOS.

    Does anyone have a route to do that ? My Cocoa/Objective C skills are not so strong; I'm thinking

    QWidget::winId() gets me an NSView, use [nsview window] to get an NSWindow and then window.titlebarAppearsTransparent = true; window.backgroundColor = my_colour; but it seems to me that I would need to access some Qt internals that are not exposed to me.


  • Qt Champions 2017

    Hi
    Qt do not draw or handle the title bar on any platform.
    Im 100% macintosh noob so might be different on that OS but on windows or
    linux you cannot directly from Qt change the color as it not controlled by Qt at all.



  • Hi mrjj,

    My understanding is that Qt wraps native widgets as much as possible so I am looking for way to effect a titlebar colour change in a Qt friendly way.

    If I can access the native elements, such as with QWidget::winId() then maybe it's possible to do it but I don't know enough about Mac and Objective C which is why I am asking here.



  • If anyone still searches a solution to this - here some tested code (Qt 5.10, macOS High Sierra):

    changetitlebarcolor.mm:

    #include <QWidget>
    #import <Cocoa/Cocoa.h>
    
    extern "C" void changeTitleBarColor(WId winId, double red, double green, double blue) {
        if (winId == 0) return;
        NSView* view = (NSView*)winId;
        NSWindow* window = [view window];
        window.titlebarAppearsTransparent = YES;
        window.backgroundColor = [NSColor colorWithRed:red green:green blue:blue alpha:1.];
    }
    

    In your main window class:

    extern "C" void changeTitleBarColor(WId winId, double red, double green, double blue);
    
    MainWindow::MainWindow() {
        changeTitleBarColor(winId(), 15./255., 29./255., 46./255.);
    

    This example will change the title bar color to a dark blue...



  • If anyone can figure out how to implement the above code, please let me know. When I try to build a sample project with nothing but this external function, all I get are expected unqualified-id errors in NSObjCRuntime.h, NSObject.h, etc. I put the .mm in OBJECTIVE_SOURCES in my .pro file as it seemed like the right thing to do.



  • I think you have to add this to your .pro :

    macx {  
     LIBS +=	 -framework AppKit
    }
    


  • @mpergand That doesn't seem to change anything, unfortunately. I'm pretty sure the issue has something to do with make trying to interpret the Objective C++ as pure C++. Have no clue how to get around this tho.


  • Lifetime Qt Champion

    Hi,

    Use Objective-C++

    main.mm

    #include <QApplication>
    #include <QWidget>
    
    #include <AppKit/AppKit.h>
    
    int main(int argc, char **argv)
    {
        QApplication app(argc, argv);
        QWidget w;
        w.show();
    
        NSView* view = (NSView*)w.effectiveWinId();
        NSWindow* window = [view window];
        window.titlebarAppearsTransparent = YES;
        window.backgroundColor = [NSColor colorWithRed:1. green:0. blue:0. alpha:1.];
    
        return app.exec();
    }
    

    In your .pro file:

    OBJECTIVE_SOURCES += main.mm
    


  • @evankirkiles said in Changing window titlebar colour in macOS:

    @mpergand That doesn't seem to change anything, unfortunately. I'm pretty sure the issue has something to do with make trying to interpret the Objective C++ as pure C++. Have no clue how to get around this tho.

    You need to import :
    #import <Cocoa/Cocoa.h>
    or
    #import <AppKit/AppKit.h>

    It compiles for me.

    I'm not fond of global C functions, i would use a valide C++ one instead:

    namespace Cocoa
    {
    void changeTitleBarColor(WId winId, double red, double green, double blue);
    }
    


  • @mpergand Tried that too, there must be something else that's wrong with my project, most likely with the .pro file because again the errors seem to be with make interpreting Objective-C++ code as C++.
    My .pro:

    SOURCES += \
            main.cpp \
            mainwindow.cpp \
    
    HEADERS += \
            mainwindow.h
    
    FORMS += \
            mainwindow.ui
    
    LIBS +=        -framework AppKit
    
    
    OBJECTIVE_SOURCES += \
            changetitlebarcolor.mm
    

    changetitlebarcolor.mm:

    #include <QWidget>
    #include <Cocoa/Cocoa.h>
    
    namespace Cocoa 
    {
     void changeTitleBarColor(WId winId, double red, double green, double blue) 
    {
        if (winId == 0) return;
        NSView* view = (NSView*)winId;
        NSWindow* window = [view window];
        window.titlebarAppearsTransparent = YES;
        window.backgroundColor = [NSColor colorWithRed:red green:green blue:blue alpha:1.];
    }
    }
    

    mainwindow.h:

    namespace Cocoa
     {
    void changeTitleBarColor(WId winId, double red, double green, double blue);
    }
    

    mainwindow.cpp:

    MainWindow::MainWindow() 
    {
    Cocoa::changeTitleBarColor(winId(), 15./255., 29./255., 46./255.);
    }
    

    Some of the errors produced :
    expected unqualified-id in NSObjCRuntime.h
    unknown type name 'Protocol' in NSObjCRuntime.h
    format argument not an NSString in NSObjCRuntime.h

    and similar issues in NSObject.h.



  • @SGaist That worked, thank you so much! One issue I may have however is that my main project is written in C++ and when I compile it in Objective-C++ with cmake (adding -x objective-c++ to compile flags), I get all sorts of errors with interpreting the generated .o files. I'm going to google around a bit with what I've learned here and see if I can make it work.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.