Как вывести GEdit на передний план, используя Java на Linux - PullRequest
0 голосов
/ 12 декабря 2018

Наше Java / SWT-приложение может запускать редактируемые пользователем сторонние приложения, например редакторы.В Linux (CentOS 7, Gnome 3.28.2), например, при запуске gedit он открывается нормально, но за окном нашего приложения.Странно то, что при запуске «gedit» из Терминала (gnome-terminal), GEdit появляется как самое переднее окно.

Как сказать «gedit» (или другим), что нужно запускать как переднее окноapplication?

Обновление: Когда я запускаю свое Java-приложение из IDE (IDEA), оно работает как положено (Gedit находится спереди).Если я запускаю свое приложение из shell-скрипта, оно работает как положено.Если я запускаю приложение из файла .desktop, указывающего на сценарий оболочки, Gedit не только открывает файл , но также показывает уведомление о готовности .Может, это как-то смущает z-порядок окон приложений?Или это зависит от переменных среды: при запуске из файла .desktop переменные среды DESKTOP_STARTUP_ID, GIO_LAUNCHED_DESKTOP_FILE, GIO_LAUNCHED_DESKTOP_FILE_PID доступны дополнительно, а для HISTCONTROL установлено значение ignoredups вместо ignorespace, SHLVL равно 2 вместо 4, а TERM установлено на dump вместо xterm-256color.

На основе кода Стефана Шлехта я нашел следующий код Java, который должен воспроизвести проблему:

import java.io.*;
import java.util.*;

import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class EditorOpener {

    public static void main(String[] args) {
        final Map<String, String> getenv = System.getenv();
        System.out.println(getenv);

        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setSize(500, 200);
        shell.setText("Editor Opener");
        shell.setLayout(new RowLayout());

        final Button button = new Button(shell, SWT.PUSH);
        button.setText("open gedit");

        button.addListener(SWT.Selection, event -> new Thread(() -> {
            final ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder.command("/usr/bin/gedit");
            final Map<String, String> environment = processBuilder.environment();
            System.out.println(environment);
            try {
                final Process process = processBuilder.start();
                process.waitFor();
            }
            catch (IOException | InterruptedException ex) {
                ex.printStackTrace();
            }
        }).start());

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

Необходим 2 доступа к переменным среды.

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

Теперь можно сделать много предположений (например, содержимое файла .desktop), но, возможно, лучше иметь пошаговое руководство о том, как это будет работать, например, так:

Тестовая программа

Эта SWT-программа запускает gedit через Runtime.getRuntime (). Exec.

import java.io.IOException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class EditorOpener {

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setSize(500, 200);
        shell.setText("Editor Opener");
        shell.setLayout(new RowLayout());

        final Button button = new Button(shell, SWT.PUSH);
        button.setText("open gedit");

        button.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent event) {
                String[] cmdArray = new String[] { "/usr/bin/gedit" };
                try {
                    Runtime.getRuntime().exec(cmdArray);
                }
                catch(IOException ex) {
                    ex.printStackTrace();
                }
            }

            public void widgetDefaultSelected(SelectionEvent event) {
            }
        });

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

Вызов программы Java

Программа Java вызывается из сценария оболочки, который выглядит следующим образом:

#!/usr/bin/bash
java -cp /path/to/swt.jar:/path/to/classes EditorOpener

.desktop файл

Файл .desktop, указывающий на файл оболочки, выглядит следующим образом:

[Desktop Entry]
Type=Application
Terminal=false
Name=Opener
Icon=utilities-terminal
Exec='/home/stephan/Documents/opener.sh'
Categories=Application;

Результат

При нажатиикнопка open gedit , gedit запускается, как и ожидалось, над всеми другими окнами.

Demo

Тест был выполнен на CentOS Linux 7:

gnome-shell --version

дает вывод:

GNOME Shell 3.28.3

gedit demo

0 голосов
/ 26 декабря 2018

Причина была в том, что наш .desktop файл содержал строки

StartupNotify=true
StartupWMClass=<main-class>

Удаление первой строки приводит к исчезновению проблемы.

0 голосов
/ 12 декабря 2018

Есть эта утилита wmctrl , которая может делать то, что вы хотите легко.

Для вашего случая использования вы будете использовать wmctrl -a "gedit" или что-то подобное.Со страницы руководства:

-a

Switch to the desktop containing the window <WIN>, raise the window, and give it focus.

В качестве альтернативы, вы можете просто свернуть программу и восстановить ее снова, когда geditотделка.

...