Git Product home page Git Product logo

Comments (7)

cafetestrest avatar cafetestrest commented on August 21, 2024

Behaviour is the same no matter what variable QT_QPA_PLATFORM is set to.

from copyq.

gowallasnewpony avatar gowallasnewpony commented on August 21, 2024

@cafetestrest, I have exactly the same issue, also on hyprland, are you using nixos?

from copyq.

gowallasnewpony avatar gowallasnewpony commented on August 21, 2024

@cafetestrest ahh, I just saw your first screenshot and it looks like you are also on nixos, pretty sure it has to do with that we are on nixos ...

from copyq.

cafetestrest avatar cafetestrest commented on August 21, 2024

@gowallasnewpony @hluk ,
I got it working by using the following workaround:

  1. I have a script that opens terminal with fish shell (my default choice) in Hyprland exec-once
  2. By utilising function fish_greeting to start copyq in config.fish:
function fish_greeting
  if not pidof copyq > /dev/null
      env QT_QPA_PLATFORM=wayland copyq --start-server &
  end
end

Does anyone happen to know why would it work like this? My suspicion is that hyprland with exec-once starts copyq differently than terminal (perhaps by user rather than root/service...).
Any feedback is appreciated.

from copyq.

hluk avatar hluk commented on August 21, 2024

So this does not seem like a bug in CopyQ, but a problem with how ydotool is set up.

Can you update to the latest Wayland Support command? It should print more details if a command fails.

from copyq.

cafetestrest avatar cafetestrest commented on August 21, 2024

Hi @hluk ,

My ydotool config looks like following (I've tried to remove as much hardening as possible): https://github.com/cafetestrest/nixos/blob/72b1b7ee096a6e5b43bd7173cacda5ca54cdbf29/nixos/ydotool.nix

I think I'm using the latest Wayland Support command, the one that I have right now has the following content (I was unable to locate newer one from this):

[Command]
Command="
    /*
    This adds support for KDE, Gnome, Sway and Hyprland Wayland sessions.

    For Sway and Hyprland, this requires:
    - `ydotool` utility to send copy/paste shortcuts to applications
    - `grim` for taking screenshot
    - `slurp` for selecting screenshot area

    For KDE, this requires Spectacle for taking screenshots.

    Getting current window title is not supported in KDE.

    Global shortcut commands can be triggered with:

        copyq triggerGlobalShortcut {COMMAND_NAME}

    On Gnome, clipboard monitor is executed as X11 app using XWayland.

    Links:
    - https://github.com/ReimuNotMoe/ydotool
    - https://github.com/emersion/grim
    - https://github.com/emersion/slurp
    */

    function isSway() {
        return env('SWAYSOCK').length != 0
    }

    function isHyprland() {
        return env('HYPRLAND_CMD').length != 0
    }

    function isGnome() {
        return str(env('XAUTHORITY')).includes('mutter-Xwayland')
    }

    function run() {
        var p = execute.apply(this, arguments)
        if (!p) {
            throw 'Failed to start ' + arguments[0]
        }
        if (p.exit_code !== 0) {
            throw 'Failed command ' + arguments[0] + ': ' + str(p.stderr)
        }
        return p.stdout
    }

    function swayGetTree() {
        var tree = run('swaymsg', '--raw', '--type', 'get_tree')
        return JSON.parse(str(tree))
    }

    function swayFindFocused(tree) {
        var nodes = tree['nodes'].concat(tree['floating_nodes'])
        for (var i in nodes) {
            var node = nodes[i]
            if (node['focused'])
                return node
            var focusedNode = swayFindFocused(node)
            if (focusedNode)
                return focusedNode
        }
        return undefined
    }

    function hyprlandFindFocused() {
        var window = run('hyprctl', '-j', 'activewindow')
        return JSON.parse(str(window))
    }

    function sendShortcut(...shortcut) {
        sleep(100)
        run('ydotool', 'key', ...shortcut)
    }

    global.currentWindowTitle = function() {
        if (isSway()) {
            var tree = swayGetTree()
            var focusedNode = swayFindFocused(tree)
            return focusedNode ? focusedNode['name'] : ''
        } else if (isHyprland()) {
            var focusedWindow = hyprlandFindFocused()
            return focusedWindow ? focusedWindow['title'] : ''
        }
        return ''
    }

    global.paste = function() {
        sendShortcut('42:1', '110:1', '110:0', '42:0')
    }

    var copy_ = global.copy
    global.copy = function() {
        if (arguments.length == 0) {
            sendShortcut('29:1', '46:1', '46:0', '29:0')
        } else {
            copy_.apply(this, arguments)
        }
    }

    global.focusPrevious = function() {
        hide()
    }

    var monitorClipboard_ = monitorClipboard
    monitorClipboard = function() {
        if (isGnome() && env('QT_QPA_PLATFORM') != 'xcb') {
            serverLog('Starting X11 clipboard monitor')
            setEnv('QT_QPA_PLATFORM', 'xcb')
            execute('copyq', '--clipboard-access', 'monitorClipboard')
            serverLog('Stopping X11 clipboard monitor')
            return
        }
        return monitorClipboard_()
    }

    var onClipboardChanged_ = onClipboardChanged
    onClipboardChanged = function() {
        var title = currentWindowTitle()
        if (title)
            setData(mimeWindowTitle, title)
        onClipboardChanged_()
    }

    screenshot = function(format, screenName) {
        if (isSway() || isHyprland())
            return run('grim', '-t', format || 'png', '-')
        return run(
            'spectacle',
            '--background',
            '--nonotify',
            '--pointer',
            '--output',
            '/dev/stdout',
        )
    }

    screenshotSelect = function(format, screenName) {
        if (isSway() || isHyprland()) {
            var geometry = run('slurp')
            geometry = str(geometry).trim()
            return run('grim', '-c', '-g', geometry, '-t', format || 'png', '-')
        }
        return run(
            'spectacle',
            '--background',
            '--nonotify',
            '--pointer',
            '--region',
            '--output',
            '/dev/stdout',
        )
    }

    global.triggerGlobalShortcut = function(commandName) {
        var cmds = commands()
        for (var i in cmds) {
            var cmd = cmds[i]
            if (cmd.isGlobalShortcut && cmd.enable && cmd.name == commandName)
                return action(cmd.cmd)
        }
        throw 'Failed to find enabled global command with given name'
    }"
Icon=
IsScript=true
Name=Wayland Support

from copyq.

hluk avatar hluk commented on August 21, 2024

Oh, sorry, that seems up-to-date - specifically this line: throw 'Failed command ' + arguments[0] + ': ' + str(p.stderr)

But I wonder why ydotool does not print any error. Maybe it prints an error message to stdout? Or showing the p.exit_code might help if these are well-defined in ydotool.

from copyq.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.