在GTK中,打开新外壳后将焦点返回到文本输入 [英] In GTK, return focus to text input after opening new shell

查看:66
本文介绍了在GTK中,打开新外壳后将焦点返回到文本输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下小示例在Windows和Ubuntu上的行为有所不同:

The following small example behaves differently on Windows and on Ubuntu:


  • mainShell Shell 包含一个 Text 输入和一个 Button

  • 按下按钮时,将另一个 smallShell 外壳打开 样式)

  • 打开外壳后,焦点应返回到文本输入

  • mainShell is a Shell that contains a Text input and a Button
  • when the button is pressed, another shell smallShell is opened (with a specfic style)
  • after the shell is opened, the focus should go back to the text input

在Windows上,焦点确实回到了文本输入。但是,在Ubuntu上,即使我们将 setActive setFocus 。我希望它的行为像第一种情况一样,并产生焦点。

On windows, the focus indeed goes back to the text input. On Ubuntu, however, the smallShell remains focussed, even though we call setActive or setFocus. I want it to behave like in the first case and yield the focus.

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class ShellWithoutTitleBar {
  public static void main(String[] args) {
    final Display display = new Display();
    
    final Shell mainShell = new Shell(display, SWT.SHELL_TRIM);
    mainShell.setSize(300, 200);
    mainShell.setLayout(new GridLayout());
    
    final Shell smallShell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP);
    smallShell.setSize(150, 150);
    
    Text text = new Text(mainShell, SWT.BORDER);
    
    Button button = new Button(mainShell, SWT.PUSH);
    button.setText("foo");
    mainShell.open();
    button.addMouseListener(new MouseListener() {
        @Override
        public void mouseDoubleClick(MouseEvent e) { }

        @Override
        public void mouseDown(MouseEvent e) {
            smallShell.open();
            mainShell.setActive();
            text.setFocus();
        }

        @Override
        public void mouseUp(MouseEvent e) { }
    });

    // Set up the event loop.
    while (!smallShell.isDisposed()) {
      if (!display.readAndDispatch()) {
        // If no more entries in event queue
        display.sleep();
      }
    }
    display.dispose();
  }

}

当我省略<$ c $时,一切正常c> SWT.ON_TOP 标志,但是对于我的用例而言,至关重要的是,新外壳始终位于顶部。

Everything works fine when I omit the SWT.ON_TOP flag, however it is critical for my use case that the new shell is always-on-top.

我尝试了随机方式强制将焦点移回文本输入或至少返回主shell,但似乎没有任何作用。

I have tried random ways to forcibly give the focus back to the text input or at least the main shell but nothing seems to have any effect.

有人知道这种解决方法吗?

Does anyone know of a workaround for this? Thanks a lot in advance.

推荐答案

我找到了解决方法。关键思想是

I found a workaround. The key idea is to


  1. 使用 setVisible 而不是为子外壳打开---实际上, open 明确将焦点设置到子外壳程序(请参阅文档)。

  2. 收听SWT。激活并将焦点返回到文本字段---这不起作用,例如

  1. use setVisible instead of open for the child shell --- In fact, open explicitly sets the focus to the child shell (see documentation).
  2. Listen for SWT.Activate and return the focus to the text field --- This does not work e.g. with FocusListener.

这是已修复此问题的修改版。

Here's a modified version that has this issue fixed.

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class ShellWithoutTitleBar2 {
  public static void main(String[] args) {
    final Display display = new Display();
    
    final Shell mainShell = new Shell(display, SWT.SHELL_TRIM);
    mainShell.setSize(300, 200);
    mainShell.setLayout(new GridLayout());
    mainShell.open();
    
    final Shell overlayShell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP);
    overlayShell.setSize(150, 150);
    overlayShell.setLayout(new GridLayout());
    
    Text text = new Text(mainShell, SWT.BORDER);
    
    Button button = new Button(mainShell, SWT.PUSH);
    button.setText("open overlayShell");
    button.addMouseListener(new MouseListener() {
        @Override public void mouseDoubleClick(MouseEvent e) { } 
        @Override public void mouseDown(MouseEvent e) {
            // this is the one key part of the answer. we use `setVisible` instead of `open`.
            overlayShell.setVisible(true);
        }
        @Override public void mouseUp(MouseEvent e) { }
    });
    
    // this is the other key part of the asnwer. we listen for `SWT.Activate` instead of focus or sth else.
      overlayShell.addListener(SWT.Activate, (e)-> {
          text.setFocus();
      });
      
    // Set up the event loop.
    while (!mainShell.isDisposed()) {
      if (!display.readAndDispatch()) {
        // If no more entries in event queue
        display.sleep();
      }
    }
    display.dispose();
  }

}

这篇关于在GTK中,打开新外壳后将焦点返回到文本输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆