Code:
wxButton* m_button_demo;
m_button_demo = new wxButton( m_sbSizer_src->GetStaticBox(), wxID_ANY, _("DemoButton"), wxDefaultPosition, wxDefaultSize, 0 );
m_button_demo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
m_button_demo->SetForegroundColour( wxColour( 255, 0, 0) );
When the button state is normal or pressed, the text correctly displays the color wxColour(255, 0, 0) in red. However, when the mouse moves over the button (i.e., when the button is in the current state), the text color changes to black. In the previous version 3.3.0, the current state still correctly displayed the wxColour(255, 0, 0) color. This issue occurred after updating to version 3.3.3 (the master branch as of commits on May 13, 2026).
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
This is almost certainly (I didn't have time to test it yet...) due to f3ab568 (Force standard button foreground color when highlighted on MSW, 2025-09-17). This seemed like a good idea because typically you set the background colour too when changing the foreground colour, as otherwise it risks being unreadable in at least some themes, but the current/hot state uses a different background.
I'm not sure about the best way forward here. Reverting f3ab568 would be simple, but I think it could be nice to still allow the behaviour implemented by it, at least as an opt-in. @ardovm Would you have any thoughts about this by chance?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
This is almost certainly (I didn't have time to test it yet...) due to f3ab568 (Force standard button foreground color when highlighted on MSW, 2025-09-17). This seemed like a good idea because typically you set the background colour too when changing the foreground colour, as otherwise it risks being unreadable in at least some themes, but the current/hot state uses a different background.
I'm not sure about the best way forward here. Reverting f3ab568 would be simple, but I think it could be nice to still allow the behaviour implemented by it, at least as an opt-in. @ardovm Would you have any thoughts about this by chance?
When the mouse hovers over a button, the frequent flickering of the button's text color can be very uncomfortable for the eyes. Even without rolling back the version, there needs to be a feature to control the text or background color of the current/hot state; otherwise, the style may appear abrupt on some UI interfaces. Adding a feature to control the current/hot state color can not only solve the current issue but also address the problem in #22721 (the issue originally fixed by f3ab568). I suggest the following changes, which would also give users greater control over the interface.
QQ.20260515102914.jpg (view on web)—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
wxWidgets allow setting bitmaps for many button states.
Probably the only catch-all solution would be offering to set colors as well as bitmaps for each state?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
wxWidgets allow setting bitmaps for many button states. Probably the only catch-all solution would be offering to set colors as well as bitmaps for each state?
Yes, this allows custom colors for each state, giving the UI high flexibility.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
@MrWeiCodes Please see our patch submission guidelines if you'd like to contribute to the project. In particular please note that screenshots of code is really not how we'd like to receive the proposed changes.
To provide full flexibility we would need to provide all the Set{Pressed,Disabled,Current,Focus}{Fore,Back}groundColour() functions and implement those of them that can be implemented in the ports that support it. However even in this case it's not clear what should the default behaviour be when only SetForegroundColour() is called: should it change the colour in the other states (as SetBitmap() does) or only in the normal one? I think nobody expects the custom colour to be applied at least in the disabled state...
Anyhow, for 3.3.3 I can only revert the commit referenced above and not do anything more (although contributions from others are welcome, of course) and so the question is just whether it should be done or not?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
To provide full flexibility we would need to provide all the
Set{Pressed,Disabled,Current,Focus}{Fore,Back}groundColour()functions and implement those of them that can be implemented in the ports that support it. However even in this case it's not clear what should the default behaviour be when onlySetForegroundColour()is called: should it change the colour in the other states (asSetBitmap()does) or only in the normal one? I think nobody expects the custom colour to be applied at least in the disabled state...
IMHO having the SetxxColour() methods behave same as the SetxxxBitmap() methods would cause the least surprise.
Anyhow, for 3.3.3 I can only revert the commit referenced above and not do anything more (although contributions from others are welcome, of course) and so the question is just whether it should be done or not?
IMHO the commit is worth keeping, because it applies the same logic to both foreground and background colors of the current/hot state.
Alternatively, a "non default colored" button shall just not change its colors in the current/hot state. This would be another solution to #22721.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
IMHO having the
SetxxColour()methods behave same as theSetxxxBitmap()methods would cause the least surprise.
I'm sympathetic to this argument but, again, I think nobody expects SetForegroundColour() to override the disabled colour. The custom bitmap is greyed out if no specific disabled bitmap is provided, so I think we should still use the normal disabled colour if SetDisabledForegroundColour() was not called.
Anyhow, for 3.3.3 I can only revert the commit referenced above and not do anything more (although contributions from others are welcome, of course) and so the question is just whether it should be done or not?
IMHO the commit is worth keeping, because it applies the same logic to both foreground and background colors of the current/hot state.
Yes, I understand its upside, but OTOH this is a regression...
Alternatively, a "non default colored" button shall just not change its colors in the current/hot state. This would be another solution to #22721.
I think having a button without visual indication of the current state would look bad too. But this would apply to the idea about extra functions above too, of course: if the user-provided colours are used for all states (even forgetting the disabled one for a moment), hot state would be indistinguishable.
An ugly solution would be to provide some ApplyCustomColoursInCurrentState() function, which would be relatively easy to implement. Should we do this perhaps?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
@MrWeiCodes Please see our patch submission guidelines if you'd like to contribute to the project. In particular please note that screenshots of code is really not how we'd like to receive the proposed changes.
To provide full flexibility we would need to provide all the
Set{Pressed,Disabled,Current,Focus}{Fore,Back}groundColour()functions and implement those of them that can be implemented in the ports that support it. However even in this case it's not clear what should the default behaviour be when onlySetForegroundColour()is called: should it change the colour in the other states (asSetBitmap()does) or only in the normal one? I think nobody expects the custom colour to be applied at least in the disabled state...Anyhow, for 3.3.3 I can only revert the commit referenced above and not do anything more (although contributions from others are welcome, of course) and so the question is just whether it should be done or not?
I have read your contribution guide. The rules are a bit complicated for me because my native language is not English and I use translation software. I have no experience with submitting patches, sorry. The code screenshot above is just an idea and does not implement the corresponding functionality.
IMHO having the
SetxxColour()methods behave same as theSetxxxBitmap()methods would cause the least surprise.I'm sympathetic to this argument but, again, I think nobody expects
SetForegroundColour()to override the disabled colour. The custom bitmap is greyed out if no specific disabled bitmap is provided, so I think we should still use the normal disabled colour ifSetDisabledForegroundColour()was not called.Anyhow, for 3.3.3 I can only revert the commit referenced above and not do anything more (although contributions from others are welcome, of course) and so the question is just whether it should be done or not?
IMHO the commit is worth keeping, because it applies the same logic to both foreground and background colors of the current/hot state.
Yes, I understand its upside, but OTOH this is a regression...
Alternatively, a "non default colored" button shall just not change its colors in the current/hot state. This would be another solution to #22721.
I think having a button without visual indication of the current state would look bad too. But this would apply to the idea about extra functions above too, of course: if the user-provided colours are used for all states (even forgetting the disabled one for a moment), hot state would be indistinguishable.
An ugly solution would be to provide some
ApplyCustomColoursInCurrentState()function, which would be relatively easy to implement. Should we do this perhaps?
Regarding the current/hot state indicator you mentioned, the current 3.3.3 version of the MSW test does include background highlighting. However, the text color reverts to black. If the text has a ForegroundColour set, it would look very odd for the current/hot state to turn black. At the very least, users should be allowed to specify a color themselves, as black is not suitable for all UIs.
Providing the Set{Pressed, Disabled, Current, Focus}{Fore, Back}groundColour() functionality would be the best approach for UI flexibility.
If the disabled state is not considered and only an ApplyCustomColoursInCurrentState() function is provided, then in the future, someone else might want to change the Focus state color or the Pressed color, requiring new features to be added again (requirements are always unpredictable). Currently, the only way to achieve such needs is through SetBitmap{Pressed, Disabled, Current, Focus}, but creating a bitmap for every button that simply needs a different text color is quite ridiculous.
Regarding color priority (only for the MSW platform; not familiar with other platforms):
First, check whether the user has called Set{Pressed, Disabled, Current, Focus}{Fore, Back}groundColour(). If so, use the state-specific color value. If the user does not need a specific state color, they simply will not call that function.
If the user only calls SetForegroundColour(), then apply the color to {Pressed, Current, Focus} except for {Disabled}. This is the normal behavior for most software. You would not see software like VSCODE or Visual Studio where a non-black text button suddenly changes its text color to black when the mouse hovers over it.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
Let's look at the standard MFC project that Visual Studio creates by default, and add a standard MFC Button Control in the middle.
((CMFCButton*)GetDlgItem(IDC_MFCBUTTON1))->SetTextColor(RGB(255,` 0, 0));
Then we set the button text color using the above command in the OnInitDialog initialization function. Next, let's take a look at the effect.
We see that in the MFC standard, when a button is in the current/hot state, the text color is not replaced.
Let's create another wx window as shown above.
1.gif (view on web)This is the effect of wx, which is inconsistent with the default UxTheme standard display effect of Microsoft.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
I need a feature to change the button text color when the mouse hovers over it. My issue is #26470, but vadz suggested I use a bitmap. After testing, I found that if I only set a bitmap for the button that needs to change color, when the user theme or system font changes, the button with a bitmap will look completely different from other buttons. Unless I set a bitmap for all buttons, but that would be stupid and the workload would be too heavy. I saw you mentioned in the issues that the SetForegroundColour in version 3.3.0 can change the Pressed/Current colors. I plan to roll back to version 3.3.0 and use it, calling SetForegroundColour when the mouse moves over the button, and clearing the color when the mouse moves away.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
I need a feature to change the button text color when the mouse hovers over it. My issue is #26470, but vadz suggested I use a bitmap. After testing, I found that if I only set a bitmap for the button that needs to change color, when the user theme or system font changes, the button with a bitmap will look completely different from other buttons. Unless I set a bitmap for all buttons, but that would be stupid and the workload would be too heavy. I saw you mentioned in the issues that the
SetForegroundColourin version 3.3.0 can change thePressed/Currentcolors. I plan to roll back to version 3.3.0 and use it, callingSetForegroundColourwhen the mouse moves over the button, and clearing the color when the mouse moves away. Or perhaps our product should switch to MFC or QT? Because it seems that wx doesn't even have such a basic feature.
I suggest you roll back to version 3.3.0. MFC's features are not as comprehensive as wx's. This is just a minor issue, and they will fix it soon.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.![]()
@vadz I think #26560 might not be exactly the same as this issue.
My problem is that the SetForegroundColour command behaves completely inconsistently with other GUIs (MFC, QT, JAVA, PYTHON) and standard display effects.
This issue is about achieving control over the current state color, which requires additional functionality.
I believe that f3ab568 should be rolled back to ensure that when only SetForegroundColour is used, the interface display is intuitive and consistent with other common GUIs, reducing migration difficulty.
As for the issue in #22721, it should be resolved using new features introduced later.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
I think the issue with #22721 is caused by the background color, not the text color. I noticed that in other GUIs, after changing the background color, the background color does not change when the mouse moves over it.
Only use SetTextColor [Only foreground]
CMFCButton m_Button;
m_Button.SetTextColor(RGB(255, 0, 0));
1.gif (view on web)
Use SetTextColor and SetFaceColor [foreground and background]
CMFCButton m_Button;
m_button.SetFaceColor(RGB(0, 0, 255));
m_button.SetTextColor(RGB(255, 255, 255));
1.gif (view on web)
But he can set the Hot color. [foreground and hot foreground]
CMFCButton m_Button;
m_Button.SetTextColor(RGB(255, 0, 0));
m_button.SetTextHotColor(RGB(0, 0, 255));
1.gif (view on web)
Only foreground
button = QPushButton("I Am QT Button")
button.setStyleSheet("color: red;")
1.gif (view on web)
Foreground and background
button = QPushButton("I Am QT Button", self)
button.setStyleSheet("color: white;background-color:blue;")
1.gif (view on web)
He can also set the hover color. [foreground and hot foreground]
button = QPushButton("I Am QT Button", self)
button.button.setStyleSheet("QPushButton {color: red;} \r\n QPushButton:hover {color: blue;}")
1.gif (view on web)
Only use setForeground [Only foreground]
JButton button = new JButton("I Am JAVA Button");
button.setForeground(Color.RED);
1.gif (view on web)
Use setForeground and setBackground [foreground and background]
JButton button = new JButton("I Am JAVA Button");
button.setForeground(Color.WHITE);
button.setBackground(Color.BLUE);
1.gif (view on web)
The JAVA version is a bit more complex and requires setting up a listener. Versions prior to f3ab568 could also achieve this effect through listening, but the latest version has no way to achieve this effect. [foreground and dynamic foreground]
JButton button = new JButton("I Am JAVA Button");
button.setForeground(Color.RED);
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
button.setForeground(Color.BLUE);
}
@Override
public void mouseExited(MouseEvent e) {
button.setForeground(Color.RED);
}
});
1.gif (view on web)
wxButton* button = new wxButton( this, wxID_ANY, _("I Am wxButton"), wxDefaultPosition, wxDefaultSize, 0 );
button->SetForegroundColour( wxColour( 255, 0, 0 ) );
1.gif (view on web)
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
Sorry, I don't see any difference between your issue (#26560) and this one, they both seem to be are about replacing the user-set foreground colour with the default colour when the button is active.
And as already written several times above, I do understand the problem and reverting f3ab568 would indeed fix it. But this would reintroduce the problem fixed by that commit, namely the button text becoming completely invisible in some themes and ideal would be to avoid this. I don't know what do MFC/Qt/Java do when you set the foreground colour which doesn't have enough contrast with the background, if you could check this, it would be interesting to know. But just ignoring that problem, as all the other commenters seem to do, doesn't solve it.
Thinking more about this, the original problem with the text being unreadable in "current" state comes from the fact that we used the custom foreground colour in this state but did not (and still do not) use the custom background colour, see the explicit check here: https://github.com/wxWidgets/wxWidgets/blob/3c793031820179945091a063a757b4122d0cb0e1/src/msw/anybutton.cpp#L1265
The current version is self-consistent in the sense that it doesn't use neither foreground nor background colour in this state, ensuring that the text is readable, but not allowing changing colours at all is not great. The other self-consistent solution would be to apply both the custom foreground and background colours in this state but this will look bad too because the background colour is supposed to be different in "current" state, otherwise it would be indistinguishable from the normal one. So we either need a way to create the "current" background colour from the user-specified one (by making it lighter/darker depending on whether it's light or dark, perhaps?) or require specifying this colour explicitly via some new SetCurrentBackgroundColour() for the foreground colour to be used in this state.
It would be definitely nicer to take care of this automatically but I'm not sure if this is going to work well in practice.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
In MFC, if a background is set, both the "normal" state and the "current" state will display the set background color, making it impossible to determine whether the control is in the "hot" state unless handled through custom drawing. When using only the foreground color, if the foreground color set doesn't have enough contrast with the background, another command, SetTextHotColor, is provided to solve this issue.
In QT, the same effect occurs: after setting the background color, both the "normal" state and the "current" state display the same color, making it impossible to distinguish between them. When using only the foreground color, if the foreground color set lacks sufficient contrast with the background, you can set the foreground color or background color for the "hover" state using the following command:
button = QPushButton("I Am QT Button", self)
button.button.setStyleSheet("QPushButton {color: red; background-color:white;} \r\n QPushButton:hover {color: blue; background-color:black;}")
If you only set the foreground color without setting the background color, the text may still be unrecognizable if it conflicts with the theme. This issue can be resolved by setting the "hover" property.
In Java, the same effect occurs: after setting the background color, both the "normal" state and the "current" state display the same color, making it impossible to distinguish between them. When using only the foreground color, if the foreground color lacks sufficient contrast with the background, the text will also be hard to read. This issue can be addressed by implementing a "MouseListener" to monitor the "hot" state and change the foreground color accordingly.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
@vadz by making it lighter/darker depending on whether it's light or dark is also a good idea.When not setting the background color for the hot state, we can first convert the background color of the normal state to grayscale. The code is as follows.
#define RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10)
The range of grayscale colors is 0-255. If the background color is greater than 128, we consider it to be relatively dark, and it can become brighter when the mouse moves over it. Conversely, if the background color is less than 128, we consider it to be relatively light, and it can become darker when the mouse moves over it. However, it seems there is currently no other reference solution available. Is this appropriate?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
We don't need this RGB2GRAY() macro, we already have wxColour::MakeGrey(), but then we also already have wxColour::ChangeLightness() which could be used to try to construct a suitable background "current" colour, I'm just not sure if it's really going to work well enough in practice.
Again, if somebody can try it/experiment with it and check if it works well enough, it would be welcome.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
We don't need this
RGB2GRAY()macro, we already havewxColour::MakeGrey(), but then we also already havewxColour::ChangeLightness()which could be used to try to construct a suitable background "current" colour, I'm just not sure if it's really going to work well enough in practice.Again, if somebody can try it/experiment with it and check if it works well enough, it would be welcome.
@vadz I built a Demo to test making buttons lighter or darker using Gray threshold or Lightness threshold.
Used to test whether this solution works well enough in practice.
But I cannot judge on my own whether it works well enough in practice.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
We don't need this
RGB2GRAY()macro, we already havewxColour::MakeGrey(), but then we also already havewxColour::ChangeLightness()which could be used to try to construct a suitable background "current" colour, I'm just not sure if it's really going to work well enough in practice.
Again, if somebody can try it/experiment with it and check if it works well enough, it would be welcome.@vadz I built a Demo to test making buttons lighter or darker using Gray threshold or Lightness threshold. Used to test whether this solution works well enough in practice. But I cannot judge on my own whether it works well enough in practice.
I watched your demo, which taught me how to achieve the effect I want by overloading the wxButton class in the latest version of wxWidgets. However, changing every button to a new class is quite troublesome, as each project requires a separate implementation, and it will need to be changed back once the issue is fixed later. I hope this issue can be fixed as soon as possible.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()