Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add .desktop prompt launcher #651

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

tulth
Copy link
Contributor

@tulth tulth commented Nov 21, 2021

Description

Add a prompt bar that can launch .desktop files.

Example use

import XMonad.Prompt.DotDesktop ( appLaunchPrompt )

myDotDeskTopLaunch = appLaunchPrompt (
  myXPConfig { complCaseSensitivity = CaseInSensitive
             , searchPredicate = fuzzyMatch
             , sorter = fuzzySort
             , maxComplRows = Just 2
             })

myKeymap :: [(String, X ())]
myKeymap =
  [ ("M-M1-d", myDotDeskTopLaunch),
...

Checklist

  • I've read CONTRIBUTING.md

  • I've considered how to best test these changes (property, unit,
    manually, ...) and concluded: XXX

  • I updated the CHANGES.md file

@tulth
Copy link
Contributor Author

tulth commented Nov 21, 2021

I am interested in reactions to this idea and if there is a better way to go about it.

I am very happy with this in my setup. It is particularly useful for launching steam games.

XMonad/Prompt/DotDesktopParser.hs Outdated Show resolved Hide resolved
XMonad/Prompt/DotDesktop.hs Outdated Show resolved Hide resolved
XMonad/Prompt/DotDesktop.hs Outdated Show resolved Hide resolved
Comment on lines 35 to 45
cmdFilter :: String -> String -- fixme future do something other than dropping these
cmdFilter ('%':'f':xs) = cmdFilter xs
cmdFilter ('%':'F':xs) = cmdFilter xs
cmdFilter ('%':'u':xs) = cmdFilter xs
cmdFilter ('%':'U':xs) = cmdFilter xs
cmdFilter ('%':'c':xs) = cmdFilter xs
cmdFilter ('%':'k':xs) = cmdFilter xs
cmdFilter ('%':'i':xs) = cmdFilter xs
cmdFilter ('%':'%':xs) = '%' : cmdFilter xs
cmdFilter (x:xs) = x : cmdFilter xs
cmdFilter "" = ""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this doesn't look fun :) I'm not familiar with .desktop files at all; what exactly are you doing here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to just execute the .desktop command specified, without arguments.
Per the spec here:
https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
there are many field codes for arguments which I cannot pass directly to the shell to execute, so I just remove them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to see if using xdg-open to run it gives you more options.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand how I would use xdg-open? Could you provide an example?

Just for context, here is an example from gimp.desktop:

[Desktop Entry]
Version=1.0
Type=Application
Name=GNU Image Manipulation Program
...
Exec=gimp-2.10 %U
...

Basically the user could type image, fuzzyMatch finds and displays GNU Image Manipulation Program, and if it is selected, the Exec is gimp-2.10 %U. This code filters out the %U and passes gimp-2.10 to the shell to launch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gtk-launch or kioclient5 exec can be used to run a .desktop file: https://askubuntu.com/a/1114798/950919

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gtk-launch is (well, at least on my distro) installed with the gtk package itself, so chances are users will definitely have this installed.

Will the fact that it goes into /usr/share/applications by itself be a problem? Out of the current paths that the code searches (~/.local/share/applications, /usr/share/applications, and /usr/local/share/applications) on the first one seems not to get searched by gtk-launch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gtk-launch does look into ~/.local/share/applications here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mh, doesn't work on my end; a .desktop file that's only in ~/.local/share/applications but not in any of the other directories will fail to be found

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's really weird, I looked into the source of gtk/glib and I don't see why it wouldn't look there. Maybe try stracing it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh indeed, strace tells me that the directory is searched. Upon closer inspection, the .desktop file contains a non-existant executable; instead of telling me that, gtk-launch told me that the .desktop file couldn't be found, however ._.

XMonad/Prompt/DotDesktop.hs Outdated Show resolved Hide resolved
@tulth
Copy link
Contributor Author

tulth commented Nov 22, 2021

Mh, doesn't work on my end; a .desktop file that's only in ~/.local/share/applications but not in any of the other directories will fail to be found

Arg! How strange. I introduced some broken desktop files and logging locally to double check the behavior on my end and I cannot seem to reproduce the issue yet.

logging diffs:

modified   XMonad/Prompt/DotDesktop.hs
@@ -54,6 +54,8 @@ getDirContents dir = do
 getDotDesktopApps :: IO [DotDesktopApp]
 getDotDesktopApps = do
   appFolders <- getAppFolders
+  appendFile "/home/tulth/.xmonad/debug.log" $
+    unlines $ ("appfolder: " ++ ) <$> appFolders
   contentsPerFolder <- mapM getDirContents appFolders
   let folderFiles = join $ rights contentsPerFolder
       dotDesktopFiles = filter isDotDesktop folderFiles
@@ -63,6 +65,7 @@ getDotDesktopApps = do
   let parseErrs = lefts parseResults
       dotDesktopApps = rights parseResults
   mapM_ print parseErrs
+  appendFile "/home/tulth/.xmonad/debug.log" $ unlines parseErrs
   return dotDesktopApps

I thought perhaps a parse failure in a folder would cause a bigger problem, but that was no issue on my system.
It give the expected result on my system and user and system desktops are listed, and the broken files i created show up.
debug.log:

appfolder: /home/tulth/.local/share/applications
appfolder: /usr/share/applications
Parse Resulted in no KeyVals in file /home/tulth/.local/share/applications/broken_user.desktop
Parse Resulted in no KeyVals in file /usr/share/applications/broken_system.desktop

Any ideas? Is XDG_DATA_DIRS is set or no? On my system XDG_DATA_DIRS is not set and it picks up defaults.

@slotThe
Copy link
Member

slotThe commented Nov 22, 2021

Any ideas?

Sorry, I was referring to gtk-launch in that comment, not your implementation

@slotThe slotThe mentioned this pull request Nov 30, 2021
3 tasks
@slotThe
Copy link
Member

slotThe commented Dec 5, 2021

@tulth what do you think about the idea of using gtk-launch instead? Semms like a standard tool that people will definitely have installed and would simplify this quite a bit

@tulth
Copy link
Contributor Author

tulth commented Dec 5, 2021

@tulth what do you think about the idea of using gtk-launch instead? Semms like a standard tool that people will definitely have installed and would simplify this quite a bit

I was thinking about this as well, but I do not think it makes much difference.
The .desktop files still have to be parsed to find the names and the filter out only applications. The only thing it saves is filtering out the %X patterns.

@slotThe
Copy link
Member

slotThe commented Dec 7, 2021

I was thinking about this as well, but I do not think it makes much difference. The .desktop files still have to be parsed to find the names and the filter out only applications. The only thing it saves is filtering out the %X patterns.

I don't use desktop files, so forgive my ignorance here, but the man page for gtk-launch says that it "launches an application using the given name". Does that mean there are .desktop files for things that aren't executable programs? What would those be? Wouldn't gtk-launch also ignore them or does it do other things as well?

@geekosaur
Copy link
Contributor

I note that gtk-launch also knows how to activate an already running application instead of just starting a new one. (Of course, starting a new one should also do that.) This does, however, imply that some .desktop files may contain DBus activations instead of executables.

@slotThe
Copy link
Member

slotThe commented Jan 8, 2022

@tulth any updates?

@slotThe
Copy link
Member

slotThe commented Mar 5, 2022

@tulth friendly ping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants