Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Dark mode for rufus#2713

Closed
ozone10 wants to merge 6 commits intopbatard:masterfrom
ozone10:darkRufus
Closed

Dark mode for rufus#2713
ozone10 wants to merge 6 commits intopbatard:masterfrom
ozone10:darkRufus

Conversation

@ozone10
Copy link
Contributor

@ozone10 ozone10 commented Mar 24, 2025

fix #1453

My attempt of dark mode for rufus. I was working on this before I've noticed PR #2510 and since it is working quite good I've decided to share it.
It was quite fun to remember difference between c++ and c, when I was porting some code.

This implementation has some considerations which I will not fix, such as "?" static text, green "?" in picture below, on rufus launch when in disabled state it may not look good.
There is no automatic change when user changes system dark mode. The change is not perfect for classic win32 apps, and may cause issues until app is restarted. I consider it important to not cause issues for rufus when it is doing its job such as creating bootable flash drives.
Dark mode is not implemented for system message boxes, as they are part of OS and not rufus.
It is also not implemented for "download" scripts windows.

And mainly it will work only on latest Windows 10 build 19045 and Windows 11.

image
image
image
image
image

@pbatard
Copy link
Owner

pbatard commented Mar 24, 2025

Impressive work!

I will need some time to review it, so it won't be part of the upcoming 4.7 release, but I'll see what I can to to include it into the 4.8 release. I also do appreciate how you moved as much as the new code as possible into new darkmode.c/.h sources, as it should help both with integration and with keeping things clean.

I'm frankly not to bothered about having some imperfections here and there, as I wasn't planning to spend much time on dark mode until after the expected redesign of the UI to use XAML Islands (which, just like fusion power is about always 50 years away, is about always 2 years away in the case of Rufus), and at this stage I'll be more than happy to have something not too time consuming to integrate, to silence the "DARK MODE WHEN?!?" thread. πŸ˜‰

It was quite fun to remember difference between c++ and c, when I was porting some code.

I bet it was. Sorry about that...

@ozone10
Copy link
Contributor Author

ozone10 commented Mar 25, 2025

I bet it was. Sorry about that...

No problem, it just makes me appreciate more automatic memory management. On the other hand c offers more adventure and satisfaction when code compile and run without segfault 😁.

I simplified code more since rufus is using quite basic sets of common controls and as I said I won't be implementing automatic mode change, thus I also removed code related to it.

I will do this PR with multiple commits, for easier review.
Just before merging I will squash PR into single commit.

Note that I am currently not planing to add another commits.

@ozone10
Copy link
Contributor Author

ozone10 commented Apr 10, 2025

Resolve conflict and fix leak.

@pbatard
Copy link
Owner

pbatard commented May 20, 2025

Thanks for keeping the PR up to date.

Considering that there are already a lot of major changes for 4.8, and that I am heaving towards an "early" release of that version, I think I will delay this PR to the 4.9 release (which, in terms of timeframe, I can only say should happen in a month ending in 'ember' this year). But then, provided that there aren't major regressions found in 4.8, I will try to bump the merging of this PR early into the 4.9 release work.

@ozone10
Copy link
Contributor Author

ozone10 commented May 22, 2025

@pbatard
I am currently getting an "Access violation reading location" error in the MSVC x64 release build on Windows 11, debug, x86, and MinGW builds work without issue. On Windows 10 there is no error for x64 build. I also tested builds with commit tags v4.7 and v4.6 in case if it was caused by recent commits, but the issue persists. Maybe some OS updates broke something.

I did quick debugging and it seems to be caused by strtoul in this line.

version = (((uint8_t)strtoul(&buf[i], &p, 10)) << 8) + (uint8_t)strtoul(&p[1], &p, 10);

@pbatard
Copy link
Owner

pbatard commented May 22, 2025

Hmm, I'm not seeing that issue at all, be it with the release binaries I am compiling or the Actions build ones. I tested on 3 different physical Windows 11 machines, all fully up to date (and with some different editions there too, as well as quite different hardware) but did not see any issue.

Considering that we are invoking GetSyslinuxVersion() on startup, I expect you get the issue as soon as you launch Rufus, but then I am unclear if you experience a crash, or just a report in the Visual Studio console (that does report some errors that can be ignored, such as Exception thrown at 0x00007FFFDBD49F0A (KernelBase.dll) in rufus.exe: 0x000006BA: The RPC server is unavailable.).

At any rate, I am not seeing any of it, and users of the Windows Store version (that is using release MSVC x64 binaries) are also not sending reports of an issue, so, especially as you are not seeing the issue with Windows 10, I'm leaning towards a pure environmental issue on your side. Or are you using an insider release?

At any rate, if you believe there is an issue, and since this topic should stay focused on the Dark Mode PR, please open a separate issue, and provide a log, so that I can get a few more details (even if the application crashes, you can get a log through DebugView, but then again, you can just copy/paste the VS output as well if you're recompiling).

@ozone10
Copy link
Contributor Author

ozone10 commented May 22, 2025

@pbatard
I've created #2740

@pbatard
Copy link
Owner

pbatard commented Jun 16, 2025

@ozone10,

I'm working on integrating this patch at long last, but it seems to me like the subclassed WM_NCDESTROY messages are not being processed, which results in memory leaks. Note that you can easily check for memory leaks by simply adding the following at the very beginning of darkmode.c:

#ifdef _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif

Then when exiting the app in VS/DEBUG, you might see the following in the Output window (which, in my case, seems to be a direct result of the free() calls in WM_NCDESTROY not being honoured at all):

*** Rufus exit ***
Detected memory leaks!
Dumping objects ->
C:\Projects\rufus\src\darkmode.c(928) : {1802} normal block at 0x000001DD8AC262F0, 8 bytes long.
 Data: <A(      > 41 28 0A 06 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1801} normal block at 0x000001DD8AC26B60, 16 bytes long.
 Data: <                > 0A 00 01 00 00 00 00 00 04 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1800} normal block at 0x000001DD8AC271F0, 16 bytes long.
 Data: <                > 0A 00 01 00 00 00 00 00 08 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1799} normal block at 0x000001DD8AC270B0, 16 bytes long.
 Data: <                > 0A 00 01 00 00 00 00 00 08 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1798} normal block at 0x000001DD8AC266B0, 16 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1797} normal block at 0x000001DD8AC26930, 16 bytes long.
 Data: <                > 0A 00 01 00 00 00 00 00 04 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1796} normal block at 0x000001DD8AC26A70, 16 bytes long.
 Data: <                > 0A 00 01 00 00 00 00 00 04 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1795} normal block at 0x000001DD8AC25EE0, 16 bytes long.
 Data: <                > 0A 00 01 00 00 00 00 00 01 00 00 00 00 00 00 00 
C:\Projects\rufus\src\darkmode.c(581) : {1794} normal block at 0x000001DD8AC27010, 16 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
Object dump complete.

I'm still working on troubleshooting it, but if you also see the same behaviour and have some idea, I'll take it.

PS: Please do not update the patch if you have a solution, as I have already integrated and modified the PR in my working tree (which may potentially be the cause of my issue), so I won't be able to use an altered patch. Instead, I'd rather have some hints on how we can get those WM_NCDESTROY messages being processed.

@pbatard
Copy link
Owner

pbatard commented Jun 16, 2025

Aha! Looks like it all boils down to the main proc of Rufus calling EndDialog() rather than DestroyWindow() at:

rufus/src/rufus.c

Line 2326 in 9a32dba

EndDialog(hDlg, 0);

None of the WM_DESTROY/WM_NCDESTROY (including the ones we have in our main loop) trigger as a result.
What I don't really get is how I never saw leaks from the stuff we (were supposed to) clean up in the main loop on DESTROY, since we've pretty much carried this issue from the beginning of Rufus...

@ozone10
Copy link
Contributor Author

ozone10 commented Jun 16, 2025

@pbatard
IIRC EndDialog will not destroy window immediately, but it will leave it to system. But it might have strange interaction with "non-dialog box" windows.

Subclass should be removed in WM_NCDESTROY with free() too.
https://devblogs.microsoft.com/oldnewthing/20031111-00/?p=41883

@pbatard
Copy link
Owner

pbatard commented Jun 16, 2025

Yeah, at any rate, the documentation for CreateDialogIndirect() (which is what we use to create the main dialog) explicitly states:

To destroy the dialog box, use the DestroyWindow function.

So using EndDialog() instead was always a bug, and it's a good thing we caught it.

@pbatard
Copy link
Owner

pbatard commented Jun 17, 2025

After some reformatting (to make it look more harmonized with the rest of the code) I think I'm good with the PR, so I am going to push the commit that closes it in a few moments.

Massive thanks to @ozone10 again for working on this. I'm sure a lot of folks will greatly appreciate it!

@pbatard pbatard closed this in 170440e Jun 17, 2025
@ozone10 ozone10 deleted the darkRufus branch June 18, 2025 19:32
@ozone10
Copy link
Contributor Author

ozone10 commented Jun 18, 2025

You are welcome. It was good experience working with "c" again after long time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dark theme

2 participants

Comments