为什么调整一个模态Qt对话框使它不再停留在其父在ctwm窗口管理器的顶部?



我调用了模态QDialog的resize-方法。我希望这不会影响其始终在顶部的行为,但现在有可能将父窗口再次带到前面。

当模式打开时,父窗口仍然无法进行交互(在这种情况下,X/C/Ctrl+Q键绑定)。

为什么会发生这种情况?

我的窗口管理器是运行在X11上的twm衍生物(ctwm-4.0.3),在xfce4上不会发生。

我按X打开调整大小对话框,按C打开"正常"对话框。一。

此外,如果我是手动调整模态大小的人,然后尝试在它上面增加父元素,这个问题也是可重复的,下面进一步概述了一些注意事项。

import sys
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QApplication, QWidget, QShortcut, QDialog
class Dialog(QDialog):
def __init__(self, parent, resize):
super().__init__(parent)
self.setModal(True)
if resize:
self.setWindowTitle("Not on top")
self.setStyleSheet("QDialog {background: magenta}")
self.resize(QSize(600,600))
else:
self.setWindowTitle("Always on top")
self.setStyleSheet("QDialog {background: purple}")
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Parent window")
self.setStyleSheet("MainWindow {background: orange}")
shortcut = QShortcut("Ctrl+Q", self)
shortcut.activated.connect(self.close)
shortcut = QShortcut("X", self)
shortcut.activated.connect(self.show_resized_dialog)
shortcut = QShortcut("C", self)
shortcut.activated.connect(self.show_dialog)
self.show()
def show_resized_dialog(self):
dialog = Dialog(self, True)
dialog.show()
self.raise_()
def show_dialog(self):
dialog = Dialog(self, False)
dialog.show()
self.raise_()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainwindow = MainWindow()
sys.exit(app.exec_())

从一些额外的实验,包括注释出所有的resizeraise_-从代码调用,然后手动调整自己的模态大小,似乎这个问题开始发生一旦模态增长到一定的大小。这个大小(宽度,高度)看起来非常一致,但是不是看起来仅仅是宽度或高度的函数吗?

例如,(width,height)=(300,300)引起它,(300,299)(299,300)也引起它——但(299,299)没有,(300,298)也没有——但(301,298)确实引起它。

(200,460)导致了这个问题,但(200,459)没有——最后一个例子是(800,100)导致了这个问题,而(100,800)没有。

由于在xfce4上无法重现,因此可能是窗口管理器问题(在本例中是ctwm)。

切换.twmrc中的各种配置选项关闭和打开,在这种情况下的问题看起来是由ctwm变量NoRaiseOnWarp设置引起的。

如果这个变量被取消设置(通过注释它),模态窗口将保持在顶部,就像它在xfce4中所做的那样(除了当父窗口在ctwm中被拖拽时,但是模态窗口将立即上升到顶部,并在拖拽操作完成后再次保持在顶部)。

ctwm手册中的变量描述为:

NoRaiseOnWarp
This variable indicates that windows should not be raised when the 
pointer is warped into them with the f.warpto function. If this option 
is set, warping to an occluded window may result in the pointer ending
up in the occluding window instead the desired window (which causes 
unexpected behavior with f.warpring).

从变量的描述中我不清楚为什么这种行为会出现在例如情态中,在CTWM邮件列表上发布一个关于它的帖子可能是一个好主意。