Setting a window icon

Hi,

I want to set up the window icon for a DocumentWindow, at the moment it's always showing some default icon. The window is using a native title bar. Calling window->setIcon(img) doesn't have any effect in this case (it just repaint the title bar drawn by JUCE if present), so I would call window->getPeer()->setIcon(img).

But this call doesn't have any effect either. I can call setIcon before or after the window is visible. It just doesn't work. The only way I can make it work is by inserting a call to setIcon() with some hard coded image just before the call to XMapWindow in LinuxComponentPeer::setVisible(). So maybe X11 requires the icon to be set before mapping the window?

--
Roeland

Here is the code I have...including the comment I wrote about a year ago when I first started playing with this on linux:

setUsingNativeTitleBar( true );
// setting the icon has to be done after setUsingNativeTitleBar() otherwise it doesn't work
setIcon( foobar::logo() );
ComponentPeer *peer = getPeer();
if ( peer )
{
    peer->setIcon( foobar::logo() );
}

I'm not sure how much of this code is still necessary.  But the fact that you're asking about it would indicate some sort of trick is still necessary.

You're correct, it has to be done after calling setUsingNativeTitleBar(), and also after calling setResizable(). And the rest of this code is definitely still necessary.

Jules, I think on both Windows and Mac all windows are getting the application icon by default. Do you think it would be possible to have this on Linux as well?

--
Roeland

+1 - StephaneCharette's code A-OK on LXDE


noticing the cautious validation of getPeer() raises the question "what could be the worst case if getPeer() returned null here?" (presumably in the MainWindow constructor) would that not be a total disaster for the entire application regardless of this icon business ?

the docs say:

This may return nullptr if there isn't a desktop component.

in which cicumstance might that be true - like a raw X environment ?

so just how naughty would this be anyway (in the MainWindow constructor)?

getPeer()->setIcon(icon_image) ;

 

@jules @fabian -

i am still curious why getPeer() may ever return null - the implication seems to be that there is no X window for JUCE to draw on - i assume this should be true for a newly created component that is not itself or has no ancestor that is attached to the desktop - but in the context of adding a window icon in the init MainWindow constructor would this be more reasonable way to handle a null ComponentPeer?

if ( getPeer() ) getPeer()->setIcon( foobar::logo() );
else             quit();

or perhaps ths is the intended use case for isValidPeer()?

ComponentPeer::isValidPeer( getPeer() )

If you create a component but don’t add it to a parent or put it on the desktop, then it’s simply an object in memory, with no peer.

ok i assumed so much - but my concern is that in the context of the mainWindow constructor addToDesktop() is done by default in a superclass ResizableWindow::initialise() - so a null ComponentPeer in the mainWindow constructor would be an unrecoverable error yes? so the only sensible thing to do would be to terminate the program

  class MainWindow : public DocumentWindow
  {
    MainWindow() : DocumentWindow( ... )
    {
      if ( getPeer() != nullptr ) getPeer()->setIcon( ... );
      else                        quit(); // or throw exception
    }
  }

Well, you should just make sure you don’t create the icon until your window has been added to the desktop, right…? Can’t really see the issue here… The constructor’s not a particularly great place to set an icon, you should maybe do it in the window’s parentHierarchyChanged callback or some other time after you know the window has been shown.

…and guys, your code examples above hurt my eyes! Do yourselves a favour and get into the habit of always using this pattern when testing and using a pointer:

if (auto peer = getPeer())
    peer->etc

It’s worth noting that, as a new user of Juce, one of the first things I was interested in doing was using a native title bar and setting an icon. There should be a tutorial for this. This isn’t something that should be a hurdle, and I shouldn’t have to dig up a four year old forum post to figure out something so basic and essential. I happened to stumble upon this post after reading several related posts that didn’t mention that getPeer()->setIcon() has to be called after setResizable(), and I was about to give up on Juce.

I’m honestly wary of using Juce due to this experience because the setIcon() documentation page does not mention any of these preconditions for the function call, and there is only a single sentence mention for setUsingNativeTitleBar() in the tutorials.

As a new user, how can I learn Juce efficiently?

There are so many things that different people thing “shouldn’t be a hurdle”. I encourage you to really consider your assertion, in the context of the important functions of a cross platform framework, and is this icon issue one of the important ones? In any case, this is a tiny piece of a large framework. What type of application are you want to develop with JUCE? and what are the larger component of JUCE that relate to that? those are the pieces you should look into first, if you want to evaluate it.

As for learning JUCE, there are a variety of tutorials you can work through (https://juce.com/learn/tutorials), as well as a bunch of content on youtube with people going over different aspects of the framework. There are also some excellent course available (and mentioned elsewhere on the forums).

If your interest is in audio, then you will be hard pressed to find a more complete and robust C++ cross platform framework.

Juce does claim to be a GUI framework. I understand there is a focus on audio plugins. The appeal for me is that using Juce is almost 100% code (as opposed to getting bogged down by a visual interface) and is written with modern C++ in mind. After watching hours of presentations and reading the GUI and Graphics tutorials, I’m not expecting to have difficulty with basic tasks like setting a title bar icon. My assertion is something that should be taken seriously. In my instance, I’m a student developing a user interface for a local Seattle company, and I’m deciding between various UI frameworks to present to them. When I present a mockup made using Juce to them, if I can’t even set an icon for the GUI, I have a feeling it will not be their favorite candidate.

Maybe you can recommend some YouTube series to me that are strictly focused on developing GUIs using Juce?

Your criteria are your own, so I won’t argue the importance of an icon on the title bar. But, the weight you keep giving to this icon is odd. Do you actually think they would reject a framework that did everything else, but make it easy to set an icon on a title bar? You can easily set the application icon, from the Projucer. You can easily set the icon for system tray functionality with SystemrayIconComponent. And, with the code provided in this discussion, you can set the titlebar icon. So, it’s not really even a case of can you or can’t you… I mean how can you trust a framework like that? :wink: anyways… :slight_smile:

I can tell you that I am a professional software engineer (of 30+ years), who has been using JUCE for 10+ years, for both my personal, and many of my professional projects. It’s a great library. As with all libraries, there are pieces that could be better, but it’s well maintained and solid code.

Lastly, I don’t have any youtube videos I can recommend.

“Do you actually think they would reject a framework that did everything else, but [did not] set an icon on a title bar?” -> Yes. By the way, this post has 1.6k views, and there are several duplicates that are more popular. This is a frequent hang up for new Juce users, and it should be addressed.

As for the rest, you’re straw manning. I’m not concerned with setting a title bar icon. I’m concerned that I have to dig up a four year old forum post to figure out how to do it. I am concerned that hang ups of this nature will be a trend using Juce, but I am hoping that this experience was an exception.

I can tell that Juce is a great library. That’s why I’m trying to use it, and trying to get a company to pay for a license to use it. But I’m not interested in repeatedly getting hung up on trivial tasks and having to dig through dead forum posts to find solutions.

Maybe you know of an open source Juce GUI that I could look at (you mentioned you use Juce in personal projects)? The demos in the tutorials are nice but it would be even nicer to see one complete project, so I can look at functioning code when documentation and tutorials fail.

I am sorry I have nothing more for you. Best of luck in your decision making process.