MouseHook удаляет текст в Mac OS X - PullRequest
0 голосов
/ 11 января 2019

Я работаю над приложением Java FX, которое включает использование «мышки» для захвата текста, выделенного мышью. Это работало без проблем при компиляции и запуске с Java 8, но в настоящее время я должен использовать Java 10, что вызвало проблему в Mac OS X (нет проблем при запуске в Windows 10).

Проблема заключается в том, что при выделении текста из документа (например, текста в TexEdit) выделенный текст удаляется и заменяется на 'c', а не копируется. Это происходит не каждый раз, но случается очень часто.

Я сократил класс mouseHook до базового теста, который показывает проблему:

Класс MouseHook --------------------------------------------- ------------

package problem;

import org.jnativehook.GlobalScreen;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;

import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;

    public class MouseHook implements NativeMouseInputListener
    {
        private static MouseHook mouseHook = null;

        private Robot mouseRobot = null;

        private boolean mouseLeftButtonDown = false;
        private boolean dragged = false;

        private MouseHook()
        {
            //disable console output from JNativeHook's internal logger (mouse-tracking, etc)
            java.util.logging.Logger logger = java.util.logging.Logger.getLogger(GlobalScreen.class.getPackage().getName());
            logger.setLevel(java.util.logging.Level.OFF);
        }

        public static synchronized MouseHook getInstance()
        {
            if(mouseHook == null)
            {
                mouseHook = new MouseHook();

                GlobalScreen.addNativeMouseListener(mouseHook);
                GlobalScreen.addNativeMouseMotionListener(mouseHook);
            }

            return mouseHook;
        }

        @Override
        public void nativeMousePressed(NativeMouseEvent e)
        {
            //If left button pressed, set mouseLeftButtonDown and look-out for dragging
            if(e.getButton() == NativeMouseEvent.BUTTON1)
            {
                mouseLeftButtonDown = true;
            }
        }

        @Override
        public void nativeMouseDragged(NativeMouseEvent e)
        {
            //only record a drag if left mouse button is held down.
            //NativeMouseEvent doesn't say which button was the source, hence test the variable.
            if(mouseLeftButtonDown)
            {
                dragged = true;
            }
        }

        @Override
        public void nativeMouseReleased(NativeMouseEvent e)
        {
            //copy text if the mouse was dragged while the left mouse button was held down.
            if(e.getButton() == NativeMouseEvent.BUTTON1)
            {
                final Timer timer = new Timer("ReleaseDetect");

                timer.schedule(new TimerTask()
                {
                    @Override
                    public void run()
                    {
                        if(dragged)
                        {
                            copy();
                            dragged = false;
                        }

                        mouseLeftButtonDown = false;

                        timer.cancel();
                    }
                }, 500);
            }
        }

        @Override
        public void nativeMouseClicked(NativeMouseEvent e)
        {}

        @Override
        public void nativeMouseMoved(NativeMouseEvent e)
        {}

        private synchronized void copy()
        {
            try
            {
                if(mouseRobot == null)
                {
                    mouseRobot = new Robot();

                    mouseRobot.setAutoDelay(100);
                    mouseRobot.setAutoWaitForIdle(true);
                }

                if(System.getProperty("os.name").toLowerCase().contains("mac"))
                {
                    mouseRobot.keyPress(KeyEvent.VK_META);
                    mouseRobot.keyPress(KeyEvent.VK_C);
                    mouseRobot.keyRelease(KeyEvent.VK_C);
                    mouseRobot.keyRelease(KeyEvent.VK_META);
                }
                else
                {
                    mouseRobot.keyPress(KeyEvent.VK_CONTROL);
                    mouseRobot.keyPress(KeyEvent.VK_C);
                    mouseRobot.keyRelease(KeyEvent.VK_C);
                    mouseRobot.keyRelease(KeyEvent.VK_CONTROL);
                }

                Thread.sleep(250);

                Transferable t=Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);

                if(t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor))
                {
                    String activeContent = (String) t.getTransferData(DataFlavor.stringFlavor);
                    System.out.println(activeContent);
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }

Класс для запуска примера ------------------------------------------ --------------

package problem;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;

public class Runnit
{
    private static MouseHook mouseHook;

    public static void main(String[] args)
    {
        try
        {
            GlobalScreen.registerNativeHook();
        }
        catch(NativeHookException e)
        {
            System.out.println("Cannot set up the NativeHook listener on the GlobalScreen");
        }

        mouseHook = MouseHook.getInstance();
    }
}

Я использую Java 10.0.2 и jNativeHook 2.1.0 от Oracle с Mac OS High Sierra (10.13.6) на Mac mini.

Кажется, проблема в том, чтобы сделать это java.awt.Robot, а не jNativeHook.

например. Если я заменю VK_C keyPress / Release на VK_B, то мышиный крюк удалит выделенный текст и заменит его на 'b'.

Моим внутренним ощущением было то, что нажатие клавиши VK_META игнорировалось. Я пытался вставить задержку до того нажатия, но это не имеет значения.

Я также пытался использовать другую мышь и чужой Macintosh, но проблема все еще возникает. Как я уже сказал, это происходит только в Mac OS X, а не в Windows 10, когда код компилируется и запускается с Java 10.

Буду признателен, если у кого-нибудь появятся идеи относительно того, является ли это безнадежным делом или есть обходной путь. Возможно, я упустил что-то очевидное, так как обычно работаю в Windows и знаком с lsss с Mac OS X.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...