-
Notifications
You must be signed in to change notification settings - Fork 112
WIP: True Borderless Window #49
base: master
Are you sure you want to change the base?
Conversation
I do not have a machine with Linux on it, therefore it would be hard for me to do the required research to replicate the same kind of behavior. Alternatively we could solve it by using the "old way" on any machine that isn't macOS or Windows. |
@Jerakin Thanks for this PR, great job. I think it is fine to break compatibility, it's a major change but with significant benefits. Regarding Linux I couldn't find a way to make the window borderless but at the same time keep snap functionality. GTK supports client side decorations and Wayland also allows applications to do so, but I failed trying on X11 + Qt... One change I'd add is to compile resources, at least for releases. It makes packaging much easier (just add & import a |
i will try on linux with x11, will report back |
# Conflicts: # qtmodern/_utils.py # qtmodern/windows.py
btw your latest commit 407d82b broke resource paths on windows for me, window buttons are not visible |
This is a great project, thank you for the hard work. Any thoughts on talking to the Qt team about sharing your work with them to add this to a future Qt release ? |
Were a typo ( |
there is another error: CLOSE_ICON = ':/icon/maximize.svg' should instead be CLOSE_ICON = ':/icon/close.svg' Another few small things I found while testing (windows):
i havent got it to work on x11 yet, will try again in the next days |
Great comments! there is another error: After minimizing/maximizing, the window button used stays selected/highlighted calling resize() or move() on QMainWindow setWindowTitle not working i havent got it to work on x11 yet, will try again in the next days |
calling resize() or move() on QMainWindow
|
calling resize() or move() on QMainWindow used to work. I know because I was using it ;) |
Actually its not working anymore. Im using an older version |
That's bad, we definitely need to figure that out. |
it does work, but you need to put it in EDIT: okay on the borderless branch you have to use resize() and move() on ModernWindow (only tried in Also I found out that closeEvent() does not get called on QMainWindow, this can be easily fixed, by adding this to ModernWindow: def __init__(self, window):
super().__init__()
self.w = window
def closeEvent(self, event):
self.w.closeEvent(event) |
@Jerakin could you give me write access to your fork, so i can commit progress on X11? Im not changing any of the other stuff. Btw its a bit more tricky than the other implementations, because you need to wait for the window to actually be created and shown, before you can make any changes to it. |
Last 2 lines below fixes that issue: def eventFilter(self, obj, event):
if event.type() == QEvent.WindowStateChange:
if self._window.windowState() == Qt.WindowMaximized:
self.btn_maximize.setVisible(False)
self.btn_restore.setVisible(True)
else:
self.btn_maximize.setVisible(True)
self.btn_restore.setVisible(False)
# brute forces hover state off
self.btn_restore.setAttribute(Qt.WA_UnderMouse, False)
self.btn_maximize.setAttribute(Qt.WA_UnderMouse, False) |
I also found a cool implementation for ModernDialog, that is far simpler than on master. class ModernDialog(QDialog, BorderlessWindow):
def __init__(self, parent):
QDialog.__init__(self, parent=parent)
BorderlessWindow.__init__(self, parent=self)
self.window_content = QWidget(self)
self.hLayout = QVBoxLayout(self)
self.hLayout.setContentsMargins(0, 0, 0, 0)
self.hLayout.setSpacing(0)
self.title_bar = _WindowsTitleBar(self, self)
self.add_window_mover(self.title_bar.lbl_title)
self.title_bar.application_icon.setVisible(False)
self.title_bar.btn_close.setVisible(False)
self.title_bar.btn_maximize.setVisible(False)
self.title_bar.btn_minimize.setVisible(False)
self.title_bar.btn_restore.setVisible(False)
self.hLayout.addWidget(self.title_bar)
self.hLayout.addWidget(self.window_content)
def setLayout(self, layout):
self.window_content.setLayout(layout) you dont need to add the titlebar if you dont want (i have hidden all widgets from it here). EDIT: Fixed |
Renamed variables so the code is easier to follow, fixed bug where self was sent in twice to _WindowsTitleBar making titles not work
I can not reproduce this, are you testing on a special window or the example window provided by qtmodern? |
was custom, will try with default but I dont think that should matter |
Some findings on X11I have spent countless hours trying to get this to work. The only thing I could not get to work, was to remove decorations (frame and buttons) from the window. Every window manager handles window decorations separately. Some use NETWM and some use Motif hints for changing properties of the window. The implementation of how to hide the default decoration will depend on the window manager used. This is already bad in itself, but could be solved. In my case KWin uses NETWM. Window hints i have tried with no or only partial success:
I have found many discussions about people requesting implementation of Other window managers support it, however we are obviously looking for a universal solution. The solution I see is to let the window manager handle the window frame. Any other application does it the same way. Then people can choose their own theme for frame and icons. It also unifies the look with the rest of the system. I will keep looking for a solution, but there might not be an easy one. |
okay i am able to reproduce this with the example window too. It happens only on my 2nd monitor (not set as primary). On my main monitor its not happening. Like i can just drag the window over and it stops working. This is very, very weird. |
NOTE: These changes may not be relevant after Qt 5.15 is released, see https://github.com/johanhelsing/qt-csd-demo |
https://www.qt.io/blog/custom-window-decorations final release planned in 3 days from now They only provide you with the following: This means For moving you can do smth like this void NativeWindow::mousePressEvent(QMouseEvent* event)
{
if (this->titleBar->underMouse())
this->windowHandle()->startSystemMove();
}; |
hi, another problem, when use the frameless window: mw = qtmwindows.ModernWindow(win) the windowIcon is disabled. is it fixed in the future version ? for example:
|
@bactone that sounds like an issue with |
Creating this PR for discussion, will not be merged in its current state.
Would like to discuss problems and solutions to using a "better" method to create a borderless window. The base work and idea of it comes from @gmarull prep work mentioned here #37 (comment). It seem to be mainly based on this repository https://github.com/dfct/TrueFramelessWindow.
Here are some discussion points:
Keep backwards compatible if possible, but this might not be feasible. If not feasible we need to discuss how we should simply bump the version as needed or do more drastic things (i.e. qtmodern2) though I do not like that solution.
Support the same platforms, if it is backwards compatible it need to support the same platforms. As of now this only have macOS and Windows support.
Keep the same simple interface, in other words wrap your application with the
modernwindow
and in simple works.Pros/Cons
There are a few upsides to doing it this way, here are some I can think of.
There are also a few downsides.
Whats left