moses-palmer / pynput

Sends virtual input commands
GNU Lesser General Public License v3.0
1.74k stars 244 forks source link

Can not get mouse event on ubuntu #524

Closed Wisgon closed 1 year ago

Wisgon commented 1 year ago

System: ubuntu22.04 Python: 3.10.8 pynput: 1.7.6

Code:

import pyperclip3 as pc

import time
from pynput.mouse import Listener, Button
from pynput.keyboard import Key, Controller

class AutoCopier:
    __press_xy = (0, 0)  # mouse position when press mouse

    def __init__(self):
        self.__keyboard = Controller()  # keyboard controller
        self.__last_click_time = 0
        self.__listener = None
        self.__listener_alive = False

    def __on_click(self, x, y, button, pressed):
        if button == Button.left:  # click left button
            if pressed:  # press left button
                print("press left~~~")
                if time.time() - self.__last_click_time < 1:  # double click
                    time.sleep(0.5)  # make sure text had been selected
                    self.__get_selected()  # word selection event, copy
                self.__press_xy = (x, y)  # record mouse postion
                self.__last_click_time = time.time()
            else:  # release left button
                if self.__press_xy != (
                    x,
                    y,
                ):  # press position is different from release position, then copy word
                    time.sleep(0.5)
                    self.__get_selected()  # word selection event, copy

    def __get_selected(self):
        last_clipbord_txt = pc.paste()  # get last text of clipboard
        with self.__keyboard.pressed(Key.ctrl):  # press ctrl
            self.__keyboard.press("c")  # press c
            self.__keyboard.release("c")  # release c
        copy_word = pc.paste()
        # if make ctrl+shift+c may cause browser open dev tool
        # if copy_word == last_clipbord_txt:
        #     # maybe linux terminal ctrl+shift+c
        #     with self.__keyboard.pressed(Key.ctrl):  # press ctrl
        #         with self.__keyboard.pressed(Key.shift):  # press shift
        #             self.__keyboard.press("c")  # press c
        #             self.__keyboard.release("c")  # release c
        #     copy_word = pc.paste()
        pc.clear()
        pc.copy(last_clipbord_txt)  # recover clipbord
        print("###@", copy_word)

    def start_listen(self):
        if self.__listener is None or not self.__listener_alive:
            self.__listener = Listener(on_click=self.__on_click)  # init listener
            self.__listener.start()
            self.__listener_alive = True

    def stop_listen(self):
        if self.__listener is not None and self.__listener_alive:
            self.__listener.stop()
            self.__listener_alive = False

    # 等待线程终止
    def wait_to_stop(self):
        self.__listener.join()

Problem:

When I run python script in vscode to start listen, every thing is find, I can get mouse click event, when I switch to chrome, it also work.

But, when I open an text editor window, and when the mouse is in the editor window, I can't get the mouse click event, I want to know why, and is there any solution?

Thanks.

moses-palmer commented 1 year ago

Thank you for your report.

Do you perchance log in to a Wayland session? This library does not work under Wayland, but applications running under XWayland will work. Chrome generally does that, and thus probably Electron based applications such as VSCode as well.

I will close this issue since this is a known limitation. Please reopen if you think that is incorrect.

Wisgon commented 1 year ago

OK, thank you.