Comments (68)
I've pushed new code. The mainwindow issue is now solved.
from framelesshelper.
I'm going to separate the frameless code and acrylic blur code within few days. This repo will only contain the frameless helper code.
from framelesshelper.
Ok, so I took the time to inherit my QMainWindow
from QtAcrylicWidget
. The window is now movable, I believe this is mandatory with the current state of the repo.
Now the next thing is that the frame is not drawn everywhere, specially when there are QToolBars
or QDockWidgets
. I suppose the contentmargin only applies on the contentWidget. Do you have any trick in mind @wangwenx190 ?
from framelesshelper.
However I think the initial target of this repo was to get a working frameless mainwindow, and I'm kinda lost how to do this with latest code.
I only changed the way of how the window blur, the frameless part is not touched except for some cleanups. But I did change the way of how to make a window frameless last year. I added a simple class called FramelessWindowsManager
, it's cross-platform. If you want to remove a window's frame, just call FramelessWindowsManager::addWindow(window)
. And the addIgnoreObject function is called FramelessWindowsManager::addIgnoreObject(window, object)
. It's just an interface class, the actual frameless code is not changed.
Is QtAcrylicWidget in charge of drawing the coloured frame?
Ok, so I took the time to inherit my QMainWindow from QtAcrylicWidget. The window is now movable, I believe this is mandatory with the current state of the repo.
Well, the QtAcrylicWidget
is a widget that have the Acrylic background, designed for cross-platform purpose. Originally it was not frameless, just a normal widget, but the appearance is much better when the window frame is gone, so I decided to make it frameless at the same time as well. It has the ability to draw the frame border indeed, if you look at it's header file. You can set the frame border's visibility, color and thickness.
If you only want to make a window frameless and don't need the acrylic background, it's not necessary to inherit from QtAcrylicWidget, just call FramelessWindowsManager::addWindow(window)
. It's very easy to draw a colored frame, just override the paintEvent of your QWidget/QMainWindow, and draw it using QPainter yourself. If you don't know how to do it, just look at qtacryliceffecthelper.cpp
, see how paintWindowFrame()
does. It's even easier for Qt Quick applications. Just put a transparent rectangle with a colored border on the top.
from framelesshelper.
Do you plan to restore the QMainWindow example I had contributed to?
I can add it back, if you wish me to do this.
Does it still work on your side?
Of course, as what I said above, the frameless code is not changed. If it works before, it will continue working.
Or is it a feature of FramelessWindowsManager?
FramelessWindowsManager won't do anything except making windows frameless. The window frame is draw either by qtacryliceffecthelper or the user himself.
Now the next thing is that the frame is not drawn everywhere, specially when there are QToolBars or QDockWidgets. I suppose the contentmargin only applies on the contentWidget. Do you have any trick in mind
The QtAcrylicWidget is just finished and I haven't test put some complex controls on it. But I'm busy dealing with the Acrylic background these days, so I do not have time to try this use case. Do you have any snapshots of this issue? Can you paste them here?
from framelesshelper.
I guess you don't need the Acrylic background. Then what about just use FramelessWindowsMananger to make the window frameless and draw the colored window frame manually in paintEvent? Will that help?
from framelesshelper.
If you only want to make a window frameless and don't need the acrylic background, it's not necessary to inherit from QtAcrylicWidget, just call
FramelessWindowsManager::addWindow(window)
.
This is what I did but ended up with the issues describes in my first post.
It's very easy to draw a colored frame, just override the paintEvent of your QWidget/QMainWindow, and draw it using QPainter yourself.
Not so easy to handle the frame color, maximized state, etc. Why reinvent the wheel if everything is already in QtAcrylicWidget.
from framelesshelper.
This is what I did but ended up with the issues describes in my first post.
I remember you provided a small trick to make it work with QMainWindow, you just need to use that again. I need to repeat this again: I didn't change the frameless code, I only changed the way of how the window blur. What works before should also continue to work now.
Not so easy to handle the frame color, maximized state, etc.
Yes, you'll have to handle all those things manually if you want to draw the window frame yourself. It's quite annoying indeed.
Why reinvent the wheel if everything is already in QtAcrylicWidget.
Because currently QtAcrylicWidget will draw the acrylic background unconditionally. I'm not sure whether you want it. You can disable the acrylic background by commenting the m_acrylicHelper.paintWindowBackground(&painter, event->region());
line though. However, the reason why I provide the QtAcrylicWidget class is to make it easier for the users who want a acrylic background, so I won't change the code. You can modify the code yourself to meet your own needs, of course.
from framelesshelper.
So I restored the example and indeed it works without subclassing QtAcrylicWidget
, but of course the frame is missing. My next step is to work on this.
from framelesshelper.
Inheriting from QtAcrylicWidget gives interesting results (weird blur when resising) but the outline is there.
One pixel is missing at the bottom of the titlebar, and the QDockWidgets titlebars also have the frame missing
from framelesshelper.
the QDockWidgets titlebars also have the frame missing
QtAcrylicWidget will only draw the frame of itself. If you want all widgets have custom frame, maybe it can't be done in this way. Subclass QStyle and draw the frame in it may work.
from framelesshelper.
Inheriting from QtAcrylicWidget gives interesting results
QtAcrylicWidget is a subclass of QWidget, not QMainWindow, I remember you told me the QDockWidget won't work under normal QWidgets, you must inherit from QMainWindow to let it work.
And the snapshot you pasted here is much more complicated than the mainwindow example I removed, is it an improved version?
from framelesshelper.
One pixel is missing at the bottom of the titlebar
Yeah I can see it from your snapshot, but currently I have no clue about it.
from framelesshelper.
Subclass QStyle and draw the frame in it may work
I'm willing to try this, but do you have an idea where this should take place?
QtAcrylicWidget is a subclass of QWidget
I changed it for a subclass of QMainWindow in my 2nd screenshot
And the snapshot you pasted here is much more complicated than the mainwindow example I removed, is it an improved version?
I think it's closer to a real application, I can commit that example on my fork if you want to take a look
There are several places where widgets seems to be drawn on top of the frame (see below) but only in frameless mode. (compare with 2nd screenshot)
from framelesshelper.
It seems the frameless QMainWindow should be one pixel bigger in order to match the normal mode and avoid QDockWidget or QToolbars overlapping the frame
from framelesshelper.
do you have an idea where this should take place?
Sorry, I'm not familiar with QStyle and its usage. I just know you can customize a widget's look and feel by implementing your own style.
I changed it for a subclass of QMainWindow
OK, that makes sense.
I can commit that example on my fork if you want to take a look
Sure, I want to add it to the official examples if you allow me to do this.
There are several places where widgets seems to be drawn on top of the frame
Looks like we need to set some kind of contents margins to leave enough space for the window frame. What do you think?
from framelesshelper.
It seems the frameless QMainWindow should be one pixel bigger in order to match the normal mode and avoid QDockWidget or QToolbars overlapping the frame
Should the window be bigger or the content need to be smaller? I think the latter is easier to achieve.
from framelesshelper.
I think the window should be bigger, but if you can explain how I can make the content smaller, let me know.
from framelesshelper.
I have just read QMainWindow's source code. It's inherited from QWidget as well. I'm going to figure out how to make a QWidget work with QDockWidgets.
from framelesshelper.
This is a simple QMainWindow demo developed by me. The green area is the menu bar, the yellow area is the status bar. From the snapshot we can see there's a large space between the widgets and the window frame. I just call setContentsMargins(50,50,50,50);
in the constructor of the QMainWindow. So the solution now is clear and quite straight forward. To leave enough space for our own window frame, we just need to call setContentsMargins()
.
from framelesshelper.
if you can explain how I can make the content smaller, let me know.
The above comment is my answer.
from framelesshelper.
I have just read QMainWindow's source code. It's inherited from QWidget as well. I'm going to figure out how to make a QWidget work with QDockWidgets.
Sadly QMainWindow is using a special home-made layout to do all the things, its source code may be thousands of lines. And it's a private helper class, not accessiable from outside. Maybe this is not a good way to explore.
from framelesshelper.
A small hint: if you are using QtAcrylicWidget or QtAcrylicEffectHelper to draw the window frame, the window frame will always be drawn in device pixel, it will always be 1px no matter what the DPI is, this is also the standard behavior of Windows. But Qt will scale your margin automatically, so actually you should do something like this:
// In Qt5, devicePixelRatio() will round dpr to integer.
// From Qt6 these two functions are the same.
const qreal m = 1.0 / devicePixelRatioF();
setContentsMargins(m, m, m, m);
But the frame thickness can be changed by calling setFrameThickness()
, but it's value will of course still be device pixels.
from framelesshelper.
from framelesshelper.
You can have a look at my branch https://github.com/JulienMaille/framelesshelper/tree/qmainwindow
I have tweaked the min/max/close icons and it really looks native now!
from framelesshelper.
You can have a look at my branch https://github.com/JulienMaille/framelesshelper/tree/qmainwindow
I have tweaked the min/max/close icons and it really looks native now!
Thanks! I'll add it to the official examples of this repo.
from framelesshelper.
Thanks! I'll add it to the official examples of this repo.
RIght now you can't, I dirty hacked QtAcrylicWidget
to inherit from QMainWindow
. I tried class templating, but QObject
doesn't support it!
from framelesshelper.
I tried class templating, but QObject doesn't support it!
QObject doesn't support template indeed.
But QtAcrylicWidget is only a thin wrapper of QtAcrylicEffectHelper, you can write a QtAcrylicMainWindow as well. Maybe you can just copy QtAcrylicWidget and rename the class name.
from framelesshelper.
I tried class templating, but QObject doesn't support it!
QObject doesn't support template indeed.
But QtAcrylicWidget is only a thin wrapper of QtAcrylicEffectHelper, you can write a QtAcrylicMainWindow as well. Maybe you can just copy QtAcrylicWidget and rename the class name.
Yes I could copy paste in a new class but that sounds dirty.
from framelesshelper.
@wangwenx190 Do you want me to duplicate QtAcrylicWidget
to QtAcrylicMainWindow
and commit?
from framelesshelper.
@wangwenx190 Do you want me to duplicate
QtAcrylicWidget
toQtAcrylicMainWindow
and commit?
I think it's fine, there's no better way anyway. We can improve it if we find some better way in the future.
from framelesshelper.
Once it's done, I think your QMainWindow exmaple can be merged as well.
from framelesshelper.
I'm curious how the acrylic works on your side. Here the acrylic reflects the wallpaper, not the windows below.
Also it stops working on screen #2
from framelesshelper.
Here the acrylic reflects the wallpaper, not the windows below.
Yes, it's rather hard to get the contents behind the window and blur it in a high performance way. So currently I'm just bluring the wallpaper. It's much easier to do and won't have a huge performance impact.
Also it stops working on screen #2
Currently I'm only acquiring the wallpaper of the primay screen, so it stops working when the window is moved to another screen. It can be improved indeed. But first let me check how to get the wallpaper of the second screen.....
from framelesshelper.
For this repo, I think this is enough. To get the best Acrylic blur, we'll need a separate repo.
from framelesshelper.
Ok, but how do we get the "real win10 acrylic" that was working nice in Win32Demo.exe
?
from framelesshelper.
I pushed the PR, however I added an option to disable the acrylic. Showing the blurred wallpaper "through" underlying windows does not make any sense in my opinion.
from framelesshelper.
Ok, but how do we get the "real win10 acrylic" that was working nice in Win32Demo.exe?
The real Win10 Acrylic? You mean the one from UWP? It can be used in Win32 applications by using XAML Island. But it needs to modify your WinMain function, and you need to install the cppwinrt NuGet package, in one word, the project's structure will be much more complex. I'm not sure whether people can accept this.
Showing the blurred wallpaper "through" underlying windows does not make any sense in my opinion.
OK. But maybe you should allow people to do this at run-time, not only from the construct time.
from framelesshelper.
The real Win10 Acrylic? You mean the one from UWP? It can be used in Win32 applications by using XAML Island. But it needs to modify your WinMain function, and you need to install the cppwinrt NuGet package, in one word, the project's structure will be much more complex. I'm not sure whether people can accept this.
No I mean the one you had develop for Win32Demo.exe a while ago. Except for the lag when resizing, it was perfect.
OK. But maybe you should allow people to do this at run-time, not only from the construct time.
It's difficult because your overwrite a couple paremeters
setAutoFillBackground(false);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_OpaquePaintEvent);
setBackgroundRole(QPalette::Base);
from framelesshelper.
I mean the one you had develop for Win32Demo.exe a while ago
This feature is still there, just disabled by default. You can enable this by setting the environment variable _FRAMELESSHELPER_FORCE_ENABLE_MSWIN10_OFFICIAL_ACRYLIC_BLUR
and _FRAMELESSHELPER_FORCE_DISABLE_WALLPAPER_BLUR
.
Except for the lag when resizing, it was perfect.
Yeah, if it doesn't lag, it's the perfect solution indeed, and very clean, just a simple API call.
It's difficult because your overwrite a couple paremeters
Can't these things be changed at run-time?
from framelesshelper.
i tried qputenv(_flh_global::_flh_acrylic_forceEnableOfficialMSWin10AcrylicBlur_flag, "True");
but this doesn't change anything
from framelesshelper.
You need to disable the wallpaper blur first. And all the env vars should be set before the app calls the setBlurEffectEnabled function. You can try set these two env vars in your main function, at the very beginning.
from framelesshelper.
I've just tried. It works.
from framelesshelper.
Can I do this with just 2 qputenv
calls?
from framelesshelper.
Can I do this with just 2
qputenv
calls?
Of course. just call them as early as you can.
from framelesshelper.
Looks like the showEvent()
code is never executed.
from framelesshelper.
also after playing with environment variable, the blur doesn't show all the weird bugs it had before (when resizing) and it shows the windows behind, not just the wallpaper. I'm not sure why I all those issues before, when looking at windows env vars, I can't find anything related
from framelesshelper.
Looks like the
showEvent()
code is never executed.
That sounds weird! I think it's impossible. Do you have any clue?
the blur doesn't show all the weird bugs it had before (when resizing)
Previously I was trying to switch between DWM blur and wallpaper blur dynamically, but I uploaded new code without testing. It turns out that the code is not working and is causing strange behavior. I removed these code in the next commit. Maybe this is what you observed. It's not related to the env vars indeed.
from framelesshelper.
@wangwenx190 can you show (maybe try first) how I can test the acrylic blur with mainwindow
example?
I tried this without success
qputenv(_flh_global::_flh_acrylic_forceDisableWallpaperBlur_flag, "True");
qputenv(_flh_global::_flh_acrylic_forceEnableOfficialMSWin10AcrylicBlur_flag, "True");
from framelesshelper.
@wangwenx190 can you show (maybe try first) how I can test the acrylic blur with
mainwindow
example?
I tried this without successqputenv(_flh_global::_flh_acrylic_forceDisableWallpaperBlur_flag, "True"); qputenv(_flh_global::_flh_acrylic_forceEnableOfficialMSWin10AcrylicBlur_flag, "True");
Yes, I've just tried. It doesn't work indeed. For now I have no clue. It's weired. I'll investigate.
from framelesshelper.
It did work 13days ago when you told me to try it. Must have been broken by a recent commit
from framelesshelper.
The acrylic background looks normal when using the wallpaper blur mode, however, it looks weired when using traditional DWM blur. The background is not transparent at all.
from framelesshelper.
Yes, but it used to work fine, just a week or two ago!
from framelesshelper.
It may worked on your side some time ago. But from my side, it has this issue since it's first merged into master branch. I've checked the commit history within recent two weeks, it seems no critical changes were made.
from framelesshelper.
Weird! Don't we need a setAttribute(Qt::WA_TranslucentBackground)
somewhere for this to work?
from framelesshelper.
setAttribute(Qt::WA_TranslucentBackground)
I've just tried, it doesn't help. And it's not needed actually. We don't use it in QtAcrylicWidget either.
from framelesshelper.
I've figured out how to solve this strange issue. You need to subclass QtAcrylicMainWindow
and enable the acrylic blur in its showEvent
, just like what the widget demo does.
from framelesshelper.
Do you have time to fix this issue? I'm quite busy with another open source project these days, I can fix it of course, but maybe some later time.
from framelesshelper.
Yes I will try to fix it
from framelesshelper.
Thanks! Then all the code in main() can be moved into its own ctor function.
from framelesshelper.
Well, with every update, it is getting more and more complex to understand how the acrylic behaves.
Why would we need to subclass QtAcrylicMainWindow
since we already subclass QMainWindow
and reimplemented showEvent()
Actually I think it stopped working when you removed Utilities::setBlurEffectEnabled(windowHandle(), m_acrylicEnabled);
from showEvent()
Now it's called too early in setAcrylicBlur()
before m_inited == true
This will fix it:
void QtAcrylicMainWindow::showEvent(QShowEvent *event)
{
QMainWindow::showEvent(event);
updateContentMargin();
if (!m_inited) {
m_acrylicHelper.install(windowHandle());
m_acrylicHelper.updateAcrylicBrush(tintColor());
Utilities::setBlurEffectEnabled(windowHandle(), m_acrylicEnabled); // <---- HERE
connect(&m_acrylicHelper, &QtAcrylicEffectHelper::needsRepaint, this, qOverload<>(&QtAcrylicMainWindow::update));
m_inited = true;
}
}
from framelesshelper.
Now for the bonus part: the resulting exe does not lag when moving nor resizing on Win10 Build 21343 🎉
from framelesshelper.
Well, with every update, it is getting more and more complex to understand how the acrylic behaves.
I'm really sorry for it. It's becoming more and more complex indeed. Maybe I should move the Acrylic-related things to a separate repo.
Now it's called too early in setAcrylicBlur() before m_inited == true
Yes, that's the reason.
Now for the bonus part: the resulting exe does not lag when moving nor resizing on Win10 Build 21343
That's really a good news! But since we are supporting two different blur modes, are you sure you are using the real acrylic blur provided by MS?
from framelesshelper.
Now for the bonus part: the resulting exe does not lag when moving nor resizing on Win10 Build 21343
For this version, is it a insider build? Does it have an official name like "1809" or "20H1"? Is it the first version that fixes the laggying bug?
from framelesshelper.
That's really a good news! But since we are supporting two different blur modes, are you sure you are using the real acrylic blur provided by MS?
Yes, 100% sure
For this version, is it a insider build? Does it have an official name like "1809" or "20H1"? Is it the first version that fixes the laggying bug?
Yes too, insider build. I'll check the name tonite
from framelesshelper.
The insider has no special name, sorry.
I noticed that the acrylic/homemade blur work even without those lines, do we really need them?
framelesshelper/qtacrylicmainwindow.cpp
Lines 148 to 151 in 95d7299
from framelesshelper.
I'll check the name tonite
Thanks, but it's not needed now since it's a developer build.
I noticed that the acrylic/homemade blur work even without those lines, do we really need them?
The homemade blur comes from a commercial component, it has these lines, I'm not sure what's the exact usage of them, so I don't remove them for safe.
from framelesshelper.
Hi, please check this repo: https://github.com/wangwenx190/qtacrylicmaterial
from framelesshelper.
Related Issues (20)
- Global::Option::ForceHideWindowFrameBorder causes the frame border to be weird on Windows HOT 10
- 请教关于Qmainwindow的布局问题 HOT 4
- 编译问题 HOT 2
- Qt 6.6.0 Windows Unable to set geometry Issue HOT 3
- qt 6.5.3 窗口拖动改变大小时控件位置不正确 HOT 6
- ubuntu linux下用qt5.15.2版本编译报错
- MacOS最后一个窗口销毁再新建窗口崩溃分析反馈,窗口全屏状态修改分辨率异常问题求助 HOT 5
- Unable to restore window state after minimizing it when using the ApplicationWindow component from Qt controls HOT 3
- Windows下标题栏按钮tooltip重复显示 HOT 3
- closeEvent事件,对QCloseEvent事件进行ignore后,原来无边框的窗体会出现边框 HOT 2
- 把Q_OBJECT包裹在其它宏里面后,qmake编译失败 HOT 1
- quick 最小化问题
- Build error macOS HOT 1
- Build error in apple M1, when Qt is not a universal version.
- 苹果M芯片编译错误 HOT 1
- Win11 5.15.2 main 分支下的 版本
- QOpenGLFunctions 自定义控件显示问题
- 【bug】windows10下最大化和恢复按钮不显示
- 使用 QWebEngineView 之后标题栏按钮无法交互 HOT 18
- 代码问题 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from framelesshelper.