Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bottles/backend/managers/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ def install(
# create Desktop entry
bottles_icons_path = os.path.join(ManagerUtils.get_bottle_path(config), "icons")
icon_path = os.path.join(bottles_icons_path, executable.get("icon"))
ManagerUtils.create_desktop_entry(_config, _program, False, icon_path)
ManagerUtils.create_desktop_entry(_config, _program, False, icon_path, True)

if is_final:
step_fn()
Expand Down
2 changes: 1 addition & 1 deletion bottles/backend/utils/imagemagick.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ def convert(
cmd += " -flatten"

cmd += f" '{dest}'"
subprocess.Popen(["bash", "-c", cmd])
subprocess.run(["bash", "-c", cmd])
80 changes: 48 additions & 32 deletions bottles/backend/utils/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

import icoextract # type: ignore [import-untyped]

from bottles.backend.params import APP_ID

from bottles.backend.globals import Paths
from bottles.backend.logger import Logger
from bottles.backend.models.config import BottleConfig
Expand All @@ -32,6 +34,11 @@
from bottles.backend.utils.generic import get_mime
from bottles.backend.utils.imagemagick import ImageMagickUtils

import uuid
from gi.repository import GLib, Gio, Gtk, Xdp, XdpGtk4

portal = Xdp.Portal()

logging = Logger()


Expand Down Expand Up @@ -224,6 +231,7 @@ def create_desktop_entry(
skip_icon: bool = False,
custom_icon: str = "",
use_xdp: bool = False,
window: Gtk.Window = None,
) -> bool:
if not os.path.exists(Paths.applications) and not use_xdp:
return False
Expand Down Expand Up @@ -279,41 +287,49 @@ def create_desktop_entry(
f.write(f"Exec={cmd_legacy} -b '{config.get('Name')}'\n")

return True
'''
WIP: the following code is not working yet, it raises an error:
GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod
import uuid
from gi.repository import Gio, Xdp

portal = Xdp.Portal()
def prepare_install_cb (self, result):
ret = portal.dynamic_launcher_prepare_install_finish(result)
id = f"{config.get('Name')}.{program.get('name')}"
sum_type = GLib.ChecksumType.SHA1
exec = "bottles-cli run -p {} -b '{}' -- %u".format(
shlex.quote(program.get('name')), config.get('Name')
)
portal.dynamic_launcher_install(
ret["token"],
"{}.App_{}.desktop".format(
APP_ID, GLib.compute_checksum_for_string(sum_type, id, -1)
),
"""[Desktop Entry]
Exec={}
Type=Application
Terminal=false
Categories=Application;
Comment=Launch {} using Bottles.
StartupWMClass={}""".format(
exec, program.get("name"), program.get("name")
)
#TODO: Desktop Actions Configure missing
#[Desktop Action Configure]
#Name=Configure in Bottles
#Exec={}
)
#TODO: Require xdp>=1.20.1
if icon == "com.usebottles.bottles-program":
_icon = Gio.BytesIcon.new(icon.encode("utf-8"))
icon += ".svg"
_icon = Gio.File.new_for_uri(
f"resource:/com/usebottles/bottles/icons/scalable/apps/{icon}"
)
else:
_icon = Gio.FileIcon.new(Gio.File.new_for_path(icon))
icon_v = _icon.serialize()
token = portal.dynamic_launcher_request_install_token(program.get("name"), icon_v)
portal.dynamic_launcher_install(
token,
f"com.usebottles.bottles.{config.get('Name')}.{program.get('name')}.{str(uuid.uuid4())}.desktop",
"""
[Desktop Entry]
Exec={}
Type=Application
Terminal=false
Categories=Application;
Comment=Launch {} using Bottles.
Actions=Configure;
[Desktop Action Configure]
Name=Configure in Bottles
Exec={}
""".format(
f"{cmd_cli} run -p {shlex.quote(program.get('name'))} -b '{config.get('Path')}'",
program.get("name"),
f"{cmd_legacy} -b '{config.get('Name')}'"
).encode("utf-8")
)
'''
return False
_icon = Gio.File.new_for_path(icon)
icon_v = Gio.BytesIcon.new(_icon.load_bytes()[0]).serialize()
portal.dynamic_launcher_prepare_install(XdpGtk4.parent_new_gtk(window),
program.get("name"), icon_v,
Xdp.LauncherType.APPLICATION,
None, True, False, None,
prepare_install_cb)
#TODO: Rework to delay showing the toast
return True

@staticmethod
def browse_wineprefix(wineprefix: dict):
Expand Down
2 changes: 2 additions & 0 deletions bottles/frontend/widgets/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ def update(result, _error=False):
"executable": self.program["executable"],
"path": self.program["path"],
},
use_xdp=True,
window=self.window,
)

def add_to_library(self, _widget):
Expand Down
3 changes: 3 additions & 0 deletions data/data.gresource.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
<gresource prefix="/com/usebottles/bottles">
<file preprocess="xml-stripblanks" alias="appdata">@[email protected]</file>
</gresource>
<gresource prefix="/com/usebottles/bottles/icons/scalable/apps">
<file preprocess="xml-stripblanks" alias="com.usebottles.bottles-program.svg">icons/hicolor/scalable/apps/com.usebottles.bottles-program.svg</file>
</gresource>
<gresource prefix="/com/usebottles/bottles/icons/scalable/actions">
<file preprocess="xml-stripblanks" alias="bottles-steam-symbolic.svg">icons/hicolor/symbolic/apps/bottles-steam-symbolic.svg</file>
<file preprocess="xml-stripblanks" alias="external-link-symbolic.svg">icons/hicolor/symbolic/actions/external-link-symbolic.svg</file>
Expand Down