-
-
Notifications
You must be signed in to change notification settings - Fork 20
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
(Enh) Support new Pop!_OS COSMIC desktop environment #301
Comments
As far as I know the new COSMIC uses the There's a module for the keymapper There are no good references I've been able to find on how to use the necessary It should be possible at some point. I just don't know how to do it yet. |
Wanted to update this issue a bit. I don't know if I'll be able to add support for COSMIC anytime soon, even though I just managed to get a more generic That new Some references for the state of things are here, but the comments are mostly over a year old now: Now that the |
Well, I've got bad news (for me), and very good news (for you). Apparently, the best way to make something possible is to declare it to be impossible. 😮💨 Toshy now has support in the The app-specific window context could be obtained by just using some different XML protocol files from the COSMIC GitHub repo. While the method itself is virtually identical to the I definitely did not expect to figure all that out in just a few hours. "Bemused" is a good word to use here. For the moment, one piece of this will have to be started manually in order to make it work, and the exact way it works may change in the future, as I try to automate it like the Plasma solution. Or if they change how their protocols work, which I think they will at some point. But now that I figured it out once, I think I might be able to keep it working. Here's how you would start the interconnecting piece: source toshy-venv
~/.config/toshy/cosmic-dbus-service/toshy_cosmic_topl_info_dbus_svc.py Then follow the instructions at the link below to edit your config file and add the necessary variable to be set to a value of https://github.com/RedBearAK/toshy/wiki/Wlroots-Based-Wayland-Compositors After saving the change to the config file, restart the Toshy services from the tray icon menu, or run If you don't want to keep that D-Bus script open in a terminal tab all the time and watch the debugging output, you can run it in the background: source toshy-venv
nohup ~/.config/toshy/cosmic-dbus-service/toshy_cosmic_topl_info_dbus_svc.py >/dev/null 2>&1 & You should be able to close the terminal tab and have the script keep running in the background. Also, even if you keep the terminal tab open, there should be no output from running the script this way. |
Merged into the main branch, and updated the Wiki article to describe what to do for COSMIC. Will update this issue if I have the time to get it automated. |
The COSMIC apps that come with the desktop environment are still kind of basic in some ways. Not that many keyboard shortcuts are available. But most basic stuff is working after adding COSMIC Terminal to the Fixed the There's also a remap to allow I think that's a good start to having a usable experience in COSMIC. But it is still definitely an alpha quality environment, and their COSMIC apps can be pretty buggy. These changes for COSMIC in the default config file are now merged into the main branch. |
Just FYI, Cosmic uses Smithay, not wlroots. The documentation seems to be missing a step, as it I needed to run I decided to test with another Smithay based compositor: Niri. However, running toshy_cosmic_topl_info_dbus_svc.py did not output anything (other than what you get from running toshy-env), so it seems that is indeed specific to Cosmic and not Smithay. Niri did seem to work with the query_topl_mgmt_protocol.py script, though. I also tested with Qtile, which uses wlroots for it's wayland backend, and that appeared to work with query_topl_mgmt_protocol.py as well. |
I see. I'll make a note of that. Somewhere.
Quite right. I'll have to add that. The whole procedure is very crude at the moment. Later on there will be launcher scripts, maybe services.
Yeah, I would not expect anything besides COSMIC to work with that method, simply because of the way they used their own namespace for the interfaces ( It would be interesting to see the output from the query script on Niri. It does at least print out the whole list of available interfaces.
That makes sense. Qtile is the only thing I ever found actually using Seeing the dump from the query script for Qtile would also be interesting. I have limited time to mess with most of these window managers unless there's a script available to get them installed with some sort of sane defaults that a noob who only uses the major desktop environments can use. I've never really been a window manager kind of user, but have been able to get Thanks a lot for your observations. I didn't expect anyone else to respond on this issue. |
Sorry, I left the line that dumps the whole list of interfaces commented out in the "query" script: def registry_global_handler(self, registry, id_, interface_name, version):
"""Handle registry events."""
# print(f"Registry event: id={id_}, interface={interface_name}, version={version}")
if interface_name == 'zwlr_foreign_toplevel_manager_v1': I'll be uncommenting that. But the "check" script should print them all out, without proceeding further to try and actually get the window context. |
Here's the output of the check_for_toplevel_protocol.py script: https://bin.garudalinux.org/?dc9ca8103f55a049#AGeyK6KXGKWcyCh6J7Phkj2s2aEjgJub1kHYeimjaPpG (Don't want to clutter the issue, so I uploaded to a pastebin)
I didn't try it. I only tested the query_topl_mgmt_protocol.py to make sure it was getting the app class and window title. But if you'd like, I can test it out.
Here it is: https://bin.garudalinux.org/?0533b6188a612fa3#3HhF7tjT4Fbri75g2K6VZwiNDYy8vFfmkN3s9CYQQEco
I was excited to see support for wlroots and Cosmic, so I had to test it out! Let me know if there's anything else you'd like me to do. I'm more than glad to help any way I can. |
Thanks again for the info. Looks like both of them (Niri and Qtile) in theory should work just fine with the standard A pastebin is a good option, but you can also make collapsible items here with some HTML tags, like this:
Without the backslashes, of course, but with the blank line between the That makes a kind of "click to reveal/hide" spoiler tag, so issues full of code blocks can stay relatively clean. The text to be displayed (click to expand)def myfunction():
pass Oh, and if you can show me how Qtile and Niri identify themselves to |
Oh cool! Thanks for the tip. That'll be much nicer to use.
Sadly, Qtile has an error: Qtile toshy-env output (click to expand)
Niri looks OK, though: Niri toshy-env output (click to expand)
|
OK, that's definitely an error I should fix. But disappointing that Qtile doesn't seem to want to identify itself by setting one of the appropriate environment variables. If you have some time, maybe do something like:
Maybe there's something else that could be used to know when the WM is Qtile. Otherwise applying the |
If you open up Replace this: if 'unity' in _desktop_env.lower():
DESKTOP_ENV = 'unity' With this: # Protect '.lower()' method from NoneType error
if _desktop_env and 'unity' in _desktop_env.lower():
DESKTOP_ENV = 'unity' The file is in
|
I'm putting a special snowflake function in the CLICK TO EXPAND ########################################################################
## Get desktop environment
# _desktop_env = os.environ.get("XDG_SESSION_DESKTOP") or os.environ.get("XDG_CURRENT_DESKTOP")
_desktop_env = os.environ.get("XDG_CURRENT_DESKTOP") or os.environ.get("XDG_SESSION_DESKTOP")
def is_qtile_running():
"""Utility function to detect Qtile if the usual environment vars are not set/empty"""
xdg_cache_home = os.environ.get('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
wayland_display = os.environ.get('WAYLAND_DISPLAY')
display = os.environ.get('DISPLAY')
if wayland_display:
socket_path = os.path.join(xdg_cache_home, f'qtile/qtilesocket.{wayland_display}')
elif display:
socket_path = os.path.join(xdg_cache_home, f'qtile/qtilesocket.{display}')
else:
return False
return os.path.exists(socket_path)
# Check for Qtile if the environment variables were not set/empty
if not _desktop_env and is_qtile_running():
_desktop_env = 'qtile'
if not _desktop_env:
_desktop_env = None
error("ERROR: Desktop Environment not found in XDG_SESSION_DESKTOP or XDG_CURRENT_DESKTOP.")
error("ERROR: Config file will not be able to adapt automatically to Desktop Environment.")
# Protect '.lower()' method from NoneType error
if _desktop_env and 'unity' in _desktop_env.lower():
DESKTOP_ENV = 'unity' I think at this point I can also start adding things like 'qtile' and 'niri' into the keymapper as valid environments for the The bad thing about the override variable for |
Looks like it sets DESKTOP_SESSION=qtilewaylan I did find this bug: qtile/qtile#2009 So it appears it's supposed to set the XDG_*_DESKTOP variables to "qtile:wlroots", but doesn't set it correctly sometimes? |
Thanks, I'll incorporate all of that in the detection logic and filtering. |
Merged into the main branch. Both Niri and Qtile should be detected without seeing any errors from Lines 220 to 293 in 81a6447
|
Everything seems to be working fine with Qtile now. Was able to run setup, start the dbus monitor, and start toshy-config successfully. And the basic testing I did of different shortcuts in different applications all worked as expected. Repeated the process in Niri and all is working well there too. Awesome job! Thanks! |
That's good news. Main thing to fix in each environment might be the Now, I just did several things. In the keymapper, I added multiple environments to match on the # Specific DEs/WMs that should work with "wlroots" provider (list may get long):
('wayland', 'hypr'),
('wayland', 'niri'),
('wayland', 'qtile'),
('wayland', 'sway'), Then I added a context provider specific to COSMIC, separate from the I also implemented a much better way to specify which DEs/WMs should try to use The new way to do it (CLICK TO EXPAND)###################################################################################################
### SLICE_MARK_START: env_overrides ### EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
# MANUALLY set any environment information if the auto-identification isn't working:
OVERRIDE_DISTRO_ID = None
OVERRIDE_DISTRO_VER = None
OVERRIDE_VARIANT_ID = None
OVERRIDE_SESSION_TYPE = None
OVERRIDE_DESKTOP_ENV = None
OVERRIDE_DE_MAJ_VER = None
wlroots_compositors = [
# Comma-separated list of Wayland desktop environments or window managers
# that should try to use the 'wlroots' window context provider. Use the
# 'DESKTOP_ENV' name that appears when running `toshy-env`.
# 'obscurewm',
# 'unknownwm',
]
### SLICE_MARK_END: env_overrides ### EDITS OUTSIDE THESE MARKS WILL BE LOST ON UPGRADE
###################################################################################################
# leave all of this alone!
DISTRO_ID = None
DISTRO_VER = None
VARIANT_ID = None
SESSION_TYPE = None
DESKTOP_ENV = None
DE_MAJ_VER = None
env_info: Dict[str, str] = lib.env.get_env_info()
DISTRO_ID = locals().get('OVERRIDE_DISTRO_ID') or env_info.get('DISTRO_ID', 'keymissing')
DISTRO_VER = locals().get('OVERRIDE_DISTRO_VER') or env_info.get('DISTRO_VER', 'keymissing')
VARIANT_ID = locals().get('OVERRIDE_VARIANT_ID') or env_info.get('VARIANT_ID', 'keymissing')
SESSION_TYPE = locals().get('OVERRIDE_SESSION_TYPE') or env_info.get('SESSION_TYPE', 'keymissing')
DESKTOP_ENV = locals().get('OVERRIDE_DESKTOP_ENV') or env_info.get('DESKTOP_ENV', 'keymissing')
DE_MAJ_VER = locals().get('OVERRIDE_DE_MAJ_VER') or env_info.get('DE_MAJ_VER', 'keymissing')
debug("")
debug( f'Toshy config sees this environment:'
f'\n\t{DISTRO_ID = }'
f'\n\t{DISTRO_VER = }'
f'\n\t{SESSION_TYPE = }'
f'\n\t{DESKTOP_ENV = }'
f'\n\t{DE_MAJ_VER = }\n', ctx="CG")
# Make sure the 'wlroots_compositors' list variable exists before checking it.
# Older config files won't have it in the 'env_overrides' slice.
wlroots_compositors = locals().get('wlroots_compositors', [])
# Direct the keymapper to try to use `wlroots` window context for
# all DEs/WMs in user list, if list is not empty.
if wlroots_compositors and DESKTOP_ENV in wlroots_compositors:
debug(f"Will use 'wlroots' context provider for '{DESKTOP_ENV}' DE/WM", ctx="CG")
debug("File an issue on GitHub repo if this works for your DE/WM.", ctx="CG")
_desktop_env = 'wlroots'
else:
_desktop_env = DESKTOP_ENV
try:
# Help the keymapper select the correct window context provider object
environ_api(session_type = SESSION_TYPE, wl_desktop_env = _desktop_env) # type: ignore
except NameError:
error(f"The API function 'environ_api' is not defined yet. Wrong keymapper branch?")
pass You'd have to get a new zip of Toshy, reinstall, and remember to remove the older variable and replace it with the new one: wlroots_compositors = [
# Comma-separated list of Wayland desktop environments or window managers
# that should try to use the 'wlroots' window context provider. Use the
# 'DESKTOP_ENV' name that appears when running `toshy-env`.
# 'obscurewm',
# 'unknownwm',
] But right now you don't have a compositor that would need to be added to the list. They're already in the keymapper. So you can leave it empty until you try some other compositor that should be compatible with the |
Updated the Wiki article to reflect the new reality. Testing in the Fedora VM with COSMIC shows everything working as expected. In So, I think everything is working like I planned, at the moment. |
I think I just managed to automate the It should no longer be necessary to manually start the COSMIC D-Bus service, it should just work right away after logging in. Unknown compositors compatible with the Environments like Hyprland still have to set up a way to auto-run the standard startup items in I don't think I can automate any further, besides adding new compositors to the keymapper's list of compatible |
Qtile does have a shortcut of command+r to run a command, but that's not like spotlight, it's more akin to the Window's run command. Niri doesn't have any built-in launcher. But for tiling window managers like these, users will have to completely customize their key bindings anyway, so it's not worth it to try to worry about that. (For example, most use command + h,j,k,l for basic navigation, which doesn't work when toshy is running. So on my MacBook, I set it to use the function key instead of command).
Awesome! It's working great with Niri. However Qtile is having an issue: toshy-services-log output (click to expand)
However, when I run toshy-config-start-verbose it works fine. Edit: Also, I just noticed, I logged out of Qtile and in to KDE and the wlroots-dbus-service was using 100% of one of my CPU cores. Restarting toshy fixed it, though. |
Yeah, I figured there might only be a few in that space that come with a somewhat standardized shortcut ( Man, Qtile seems to be kind of a pain, doesn't it? I'm not sure what is responsible for setting You could find a way to set and export the variable yourself, maybe, but it would have to be something that only happens when logging into Qtile. I'll have to think about how I can have a fallback for that. Another dump of the
Or:
That should find anything that might be either "wl"[something] or "wlroots".
😠 I'll probably need to have that script terminate itself or just chill out if it starts having a problem with the interface, which would obviously disappear after logging out of the compatible Wayland session. (Obvious in hindsight, that is.) Probably should take a look at the COSMIC script too, to make sure it exits when not in COSMIC anymore. Thanks! |
Question, does Qtile have the same problem as Hyprland, where it's not set by default to auto-run the items in
What this does is help the I'm seeing the same thing happening in the log in Hyprland, so I think the basic problem is that the kickstart is not happening. Does the tray icon appear in Qtile? That also has a "helper" line in it that basically does the same thing, assisting the Basically, until something or someone runs a command like this, the
I'm not really sure what I can do about this other than encourage the user to set up proper processing of the There's actually a script in the https://github.com/RedBearAK/toshy/blob/main/scripts/XDG-Autostart-processor.sh In theory that will take care of getting the services to all run correctly, without manual intervention. |
I think I kind of fixed the problem that led to the Wlroots D-Bus script using CPU after you left Qtile and logged into Plasma. It should stop itself now under multiple conditions like loss of the file descriptor or non-responsive Wayland interface. But I think I also noticed something else, which is kind of like a problem in Plasma. It might be necessary to "kickstart" the window context in something like Hyprland, when running in the Maybe I'll try something similar in the |
Sure does! I'm starting to be sorry I even tried it out! ;)
So this is weird, and XDG_SESSION_TYPE is set to wayland (I even did a reboot just to double check it wasn't a remnant from logging in to KDE). It also sets a bunch of other XDG_* variables, just not the XDG_*_DESKTOP ones. But the log is still saying XDG_SESSION_TYPE is not set.
Ah! That seems to be it. I ran the systemctl command you posted and that error went away. However, a new one popped up: toshy-services-log output (click to expand)
I set Qtile to run the XDG-Autostart-processor.sh script at start but that didn't change anything (it did run, though, because I got the OpenSuse welcome message, which I wasn't getting before). Tried rebooting as well and no change. |
That would seem to indicate that my detection of Qtile is still failing. When you just run It's looking for a file like I wonder if it's not actually getting a chance to check What is the output from this?
|
toshy-env shows the correct thing: output from commands (click to expand)
I just noticed though, in the code you have "qtilewayland," but it is "qtilewaylan" without the d. |
LOL. I kind of assumed that you'd made a typo, since that makes no sense. I'll do some tweaks. |
OK, I just loaded these tweaks into the Toshy def is_qtile_running():
"""Utility function to detect Qtile if the usual environment vars are not set/empty"""
xdg_cache_home = os.environ.get('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
display = os.environ.get('DISPLAY')
wayland_display = os.environ.get('WAYLAND_DISPLAY')
desktop_session = os.environ.get('DESKTOP_SESSION')
if display:
socket_path = os.path.join(xdg_cache_home, f'qtile/qtilesocket.{display}')
elif wayland_display:
socket_path = os.path.join(xdg_cache_home, f'qtile/qtilesocket.{wayland_display}')
elif desktop_session and 'qtile' in desktop_session:
return True
else:
return False
return os.path.exists(socket_path)
# Check for Qtile if the environment variables were not set/empty
if not _desktop_env and is_qtile_running():
_desktop_env = 'qtile'
if not _desktop_env:
_desktop_env = None
error("ERR: DE not found in XDG_SESSION_DESKTOP, XDG_CURRENT_DESKTOP or DESKTOP_SESSION.")
error("ERR: Config file will not be able to adapt automatically to Desktop Environment.")
if SESSION_TYPE == 'wayland':
error("ERR: No generic Wayland window context method is currently available.")
# Protect '.lower()' method from NoneType error
if _desktop_env and 'unity' in _desktop_env.lower():
DESKTOP_ENV = 'unity'
# Produce a simplified desktop environment name
desktop_env_names = {
'Budgie': 'budgie',
'Cinnamon': 'cinnamon',
'COSMIC': 'cosmic',
'Cutefish': 'cutefish',
'DDE': 'dde',
'Deepin': 'deepin',
'Enlightenment': 'enlightenment',
'GNOME': 'gnome',
'Hyprland': 'hyprland',
'i3': 'i3',
'i3wm': 'i3',
'IceWM': 'icewm',
'KDE': 'kde',
'LXDE': 'lxde',
'LXQt': 'lxqt',
'MATE': 'mate',
'Niri': 'niri',
'Pantheon': 'pantheon',
'Plasma': 'kde',
'qtile:wlroots': 'qtile',
'Qtile': 'qtile',
'qtilewaylan': 'qtile', # actual value in real life (typo in Qtile code?)
'qtilewayland': 'qtile', # might appear if they fix the typo
'qtilex11': 'qtile',
'Sway': 'sway',
'SwayWM': 'sway',
'Trinity': 'trinity',
'UKUI': 'ukui', # Ubuntu Kylin desktop shell
'Unity': 'unity', # keep above "Ubuntu" to always catch 'unity' first
'Ubuntu': 'gnome', # "Ubuntu" in XDG_CURRENT_DESKTOP, but DE is GNOME
'Wayfire': 'wayfire',
'WindowMaker': 'wmaker',
'Xfce': 'xfce',
} |
In hindsight, I probably should've pointed out it was incorrect on their end.
I checked out the dev_beta branch and ran |
Probably not, but there may be a better way to do the detection function: def is_qtile_running():
"""Utility function to detect Qtile if the usual environment vars are not set/empty"""
xdg_cache_home = os.environ.get('XDG_CACHE_HOME', os.path.expanduser('~/.cache'))
display = os.environ.get('DISPLAY')
wayland_display = os.environ.get('WAYLAND_DISPLAY')
desktop_session = os.environ.get('DESKTOP_SESSION')
socket_paths = []
if display:
socket_paths.append(os.path.join(xdg_cache_home, f'qtile/qtilesocket.{display}'))
if wayland_display:
socket_paths.append(os.path.join(xdg_cache_home, f'qtile/qtilesocket.{wayland_display}'))
if desktop_session and 'qtile' in desktop_session.casefold():
return True
for socket_path in socket_paths:
if os.path.exists(socket_path):
return True
return False You can put that in place, save the file and just run I have a feeling it's due to the module running too early, or something? Before it will have access to the environment variables? Does this only happen at login, or also after restarting the services later, and after somehow running that |
I just noticed that you said "checked out" here and not "downloaded a new zip". If that means you just changed the branch in a cloned Which is why in testing I always download a new zip, unzip it, delete the zip file, and then after installing, delete the whole folder before unzipping a new zip file with new changes. This is the only way I've found to reliably be installing the stuff from the latest zip. Now, the solution to switching git branches in the terminal and not getting old file contents might be as simple as leaving the folder with I had a big problem early on in the project with accidentally running the setup script from the trash after deleting a folder and creating a new one, because the terminal doesn't immediately tell you the folder you were in is in the trash now. Which is why the script checks the setup script path to make sure it's not running from any kind of "trash" path. Maybe something similar happens when you Anyway, that's a possible explanation for why you still got the error, if you're doing the It is a pain to keep downloading and unzipping a new zip file, but it guarantees that what I end up installing is the exact state of the code any new user downloading the zip would end up with. |
So I had written up this long post with all the debugging I had done, and then right at the end it dawned on me. I needed to add DESKTOP_SESSION and WAYLAND_DISPLAY to the import-environment command in Toshy_Import_Vars.desktop. It still didn't work the first time logging in, but then I added sleep 5 to the start of the XDG-Autostart-processor.sh script and it worked!
I actually used |
Sorry, I was out to lunch, in the literal sense. I absolutely should have thought of that, and I'll update the tray app and that desktop file to import those new variables. Did you add the sleep to the start, or after it processes stuff? I'm assuming at the start. I'll give that a try.
See, that shows how much effort I've put into learning more about |
No worries. I was literally typing, "I even tested manually running
It's a pretty recent addition. And really nice to have when working with multiple branches simultaneously. |
I made those changes and merged them in, for the tray app, the GUI app, the var importer desktop entry, and the delay in the XDG autostart script. Also, it occurred to me that instead of messing with the keymapper, for now it would make more sense to put a primary list of compositors to shunt to # TODO: Add a list here to concat with 'wlroots_compositors', instead of
# continuing to add new environments into the 'wlroots' provider inside
# the keymapper.
known_wlroots_compositors = [
'hyprland',
'niri',
'qtile',
'sway',
]
# Make sure the 'wlroots_compositors' list variable exists before checking it.
# Older config files won't have it in the 'env_overrides' slice.
wlroots_compositors = locals().get('wlroots_compositors', [])
# Direct the keymapper to try to use `wlroots` window context for
# all DEs/WMs in user list, if list is not empty.
if wlroots_compositors and DESKTOP_ENV in wlroots_compositors:
debug(f"Will use 'wlroots' context provider for '{DESKTOP_ENV}' DE/WM", ctx="CG")
debug("File an issue on GitHub repo if this works for your DE/WM.", ctx="CG")
_desktop_env = 'wlroots'
elif DESKTOP_ENV in known_wlroots_compositors:
debug(f"DE/WM '{DESKTOP_ENV}' is in known 'wlroots' compositor list.", ctx="CG")
_desktop_env = 'wlroots'
else:
_desktop_env = DESKTOP_ENV
try:
# Help the keymapper select the correct window context provider object
environ_api(session_type = SESSION_TYPE, wl_desktop_env = _desktop_env) # type: ignore
except NameError:
error(f"The API function 'environ_api' is not defined yet. Wrong keymapper branch?")
pass |
I decided to close out this issue since the original issue, COSMIC support, is pretty much nailed down for now. I created a separate new issue thread for further discussion of other compositors that might use the Thanks for all your contributions, @armerpunkt, that was really helpful. |
Is your feature request related to a problem? Please describe.
There is not support for COSMIC.
Describe the solution you'd like
It would be nice to have support for COSMIC when it gets to alpha state.
The text was updated successfully, but these errors were encountered: