模态对话框位于 Opensuse 其他窗口的后面

Posted

技术标签:

【中文标题】模态对话框位于 Opensuse 其他窗口的后面【英文标题】:Modal dialogs stay on the back of other windows on Opensuse 【发布时间】:2013-02-06 08:16:08 【问题描述】:

在我的应用程序中,有 java SWT 编写的对话框屏幕。当打开一个模态对话框(警告/错误/文件对话框等)时,点击父屏幕后不能停留在父屏幕顶部,或者在主屏幕后面打开。该对话框只能通过按 ALT+tab 来打开。此问题发生在 Opensuse 11.04 上。它不会在 Windows 上发生。

Main 和 ShellExample 类用于测试问题。当您在打开的 shell 中按下“打开模式对话框”按钮时,FileDialog 会出现。 MessageDialog 在顶部打开,但是当单击 shell 时,它会返回。

这里是主类;

public class Main 

    /**
     * @param args
     */
    public static void main(String[] args) 
        // TODO Auto-generated method stub

        Display display = new Display();
        final Shell shell = new Shell(display);

        shell.setLocation(0,0);
        shell.setSize(500, 500);

        shell.setLayout(new GridLayout());
        FormToolkit  toolkit = new FormToolkit(shell.getDisplay());

        Button okButton = toolkit.createButton(shell, "  Open Shell  ", SWT.NONE);

        okButton.addSelectionListener(new SelectionAdapter() 
            public void widgetSelected(SelectionEvent e) 
                ShellExample mainDialog = new ShellExample(shell);
                mainDialog.open();
                
          );

        shell.open();

        while (!shell.isDisposed()) 
          if (!display.readAndDispatch()) 
            display.sleep();
          
        
        display.dispose();

    

这是 ShellExample 类;

public class ShellExample extends Dialog 

    private Shell shell;
    public ShellExample(Shell parent) 
        super(parent, SWT.NO_TRIM | SWT.PRIMARY_MODAL);
        // TODO Auto-generated constructor stub
    

    public Object open() 

        // TODO Auto-generated method stub
        shell = new Shell(getParent(), getStyle());
        createContents();

        shell.open();
        shell.layout();


        Display display = getParent().getDisplay();
        while (!shell.isDisposed()) 
            if (!display.readAndDispatch()) 
                display.sleep();
            
           
        return null;

    

    private void createContents() 
        // TODO Auto-generated method stub

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        shell.setSize(ge.getMaximumWindowBounds().width,ge.getMaximumWindowBounds().height);

        shell.setText(getText());
        shell.setLayout(new FillLayout());

        shell.setLayout(new GridLayout());
        FormToolkit  toolkit = new FormToolkit(shell.getDisplay());


        Button okButton = toolkit.createButton(shell, " open modal dialog ", SWT.NONE);

        okButton.addSelectionListener(new SelectionAdapter() 
            public void widgetSelected(SelectionEvent e) 
                FileDialog fd = new FileDialog(shell, SWT.SAVE);
                fd.setText("file dialog");
                fd.open();
             // MessageDialog.open(MessageDialog.WARNING  , shell, "warning_title", "warning_message", SWT.APPLICATION_MODAL);
            
          );

    

有什么建议吗?

谢谢。

【问题讨论】:

【参考方案1】:

在 Linux 中,由窗口管理器(Gnome、KDE、XFCE、Enlightenment 等)来实现此行为。我知道几个 Linux 窗口管理器的特殊性启示和平铺窗口管理器不支持模式窗口。要确定您尝试做的事情是否可行,您应该查看您正在使用的窗口管理器的文档,看看它是否支持它。 这可以通过查看 NET_WM 标志找到,您可能正在寻找的是 _NET_WM_STATE_MODAL 一些关于此的文档可以在免费桌面标准网站上找到,撰写本文时的最新规范是 http://standards.freedesktop.org/wm-spec/wm-spec-1.5.html

【讨论】:

我使用 Gnome 窗口管理器。我意识到如果主屏幕是全屏的,那么打开的窗口会出现在主屏幕下方。临时解决方案是不使用全屏。我也不确定这个问题的确切原因是什么,我找不到任何其他解决方案。 现在窗口管理器通常会在全屏窗口打开时关闭渲染并将显示缓冲区直接转发到显示系统,我知道如果单独弹出窗口,启蒙会禁用此功能窗口出现在顶部,并具有禁用直接通过全屏窗口的选项,在 3 分钟的谷歌搜索中,我无法看到使用 gnome 的方法。您可以通过在 gnome 错误跟踪器上打开一个关于全屏窗口创建的对话框不显示这一事实的错误来获得更多帮助。

以上是关于模态对话框位于 Opensuse 其他窗口的后面的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX如何实现模态窗口

模态对话框与非模态窗口

Qt 之 模态非模态半模态窗口的介绍及 实现QDialog的exec()方法

如何用纯Win32 API写模态窗口?

QT模态对话框及非模态对话框

QT笔记之模态对话框及非模态对话框