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

Refactored codebase to Python #63

Merged
merged 1 commit into from
Mar 4, 2024

Conversation

rsubtil
Copy link
Member

@rsubtil rsubtil commented Jan 30, 2021

Well, that took a while to complete, but here it is; all Komorebi code, fully ported to Python! 🎉

This is quite the change to review, so take all the time needed to check things! And don't hesitate to ask me questions about design decisions, or what a certain piece of code is doing, or anything really. Below I'll write a checkup of the biggest changes, key decisions, and workarounds implemented:

Refactored

  • As discussed before, since the move to Python was already a big refactor in it itself, I took the opportunity to also refactor the code itself to be more manageable. The structure is the one detailed below, and thankfully there were no big hurdles that modified the proposed structure, so it should be pretty much what I planned:

    • Main - Main class that's initialized and stores the global list of Screen's.

    • Screen - A GtkClutter window that spans the width of an individual screen. It features a single object of type Wallpaper, and a BubbleMenu instance. It can also have multiple Overlay's.

    • Wallpaper - A ClutterActor that works as the background wallpaper. Every screen uses one, but this is the base abstract type, not instantiated directly; the magic is in it's children.

      • ImageWallpaper - An image wallpaper, that can feature some dynamic effects, such as parallax and layers.
      • VideoWallpaper - A video wallpaper, that reproduces a video stream in the background.
      • WebWallpaper - A web-page wallpaper, that prevents interaction from the user.
    • Overlay - A ClutterActor that is displayed above a Wallpaper. This can be used to implement "meta" elements, independent of the current wallpaper:

      • Desktop - An overlay that simulates a desktop, allowing the user to interact with it.
      • Clock - An overlay to display the current date and time.
      • Asset - An overlay that displays an asset on top of the wallpaper and/or clock, with animation effects.
    • BubbleMenu - A menu that allows the user to change wallpaper and global settings, by launching a PreferencesWindow. It's outside of the Overlay class because it's mandatory in every Screen.

    • Utilities - An utilities file with global functions, variables, and wallpaper/overlay loading.

    • Settings - The file responsible for holding, managing and storing configurations

    • PreferencesWindow - A GtkWindow that allows to setup and modify Komorebi's configs and wallpapers. It should interface with Utilities and in some cases Main as well.

  • The Wallpaper Creator app was also rewritten to Python, but not modified; I didn't bother to refactor anything, as I'm sure this tool will be rewritten to be a much more feature-full editor, so better to write from scratch.

  • I also had to rename some folders, and move some files around, for easier integration with meson. The most notable is that src was renamed to komorebi, wallpaper-creator was moved to inside of this new folder, and the main files are in the root directory now (komorebi.in and komorebi-wallpaper-creator.in). This is debatable, so let me know if another structure would be better.

Features

  • I took the opportunity to implement a proper logging system, which should make debugging much easier. The level can be specified, from NORMAL (normal messages and warnings), INFO (more info messages of what's happening), and DEBUG (verbose description of almost everything). Here's a snippet of the output:
$ komorebi --log=DEBUG
Welcome to Komorebi
[DEBUG] (11:20:29): GtkClutter initialized
[INFO] (11:20:29): Loading configuration...
[INFO] (11:20:29): Reading config file...
[DEBUG] (11:20:29): Configuration file read
[INFO] (11:20:29): loading Gst
[DEBUG] (11:20:29): Gst initialized
[INFO] (11:20:29): Monitor Count - 1
[INFO] (11:20:29): Initializing clipboard...
[DEBUG] (11:20:29): Initializing background window for monitor 0...
[DEBUG] (11:20:29): 0 - Rectangle geometry: x=0 y=0 w=1366 h=768
[DEBUG] (11:20:29): 0 - Setting window properties...
[DEBUG] (11:20:29): Loading BubbleMenu...
[DEBUG] (11:20:29): Loaded BubbleMenu
[DEBUG] (11:20:29): Loading PreferencesWindow...
[DEBUG] (11:20:29): Loading WallpapersSelector..
[DEBUG] (11:20:29): Loaded WallpapersSelector...
[DEBUG] (11:20:29): Loaded PreferencesWindow
[DEBUG] (11:20:29): Loading VideoWallpaper...
[DEBUG] (11:20:29): Loaded VideoWallpaper
[DEBUG] (11:20:29): Loading Clock...
[DEBUG] (11:20:29): Loaded Clock
[DEBUG] (11:20:29): Loading Desktop...
[DEBUG] (11:20:29): Loaded Desktop
[DEBUG] (11:20:29): Starting Clutter backend...
...
  • More consistent arguments, and all available ones are now explained upon a pretty komorebi --help.

  • Implementing new wallpapers and overlays is surprisingly plug-and-play; wallpapers simply define their behaviours, connect to needed signals, and that's it. Same for overlays. This opens the door to implement other types of wallpapers and overlays with relative ease.

  • A workaround would be needed to implement toggling video wallpapers only after a restart... So I cleaned this up and it no longer needs a full reset to work.

Workarounds

  • Even though the base structure of the code was totally revamped, the wallpaper configuration files weren't; I've decided not to go forward with that right now, as these changes are big as it is, and I don't intend to make breaking changes right away. As a result, there is some code for "workaround" on loading wallpaper configuration; this will be properly fixed when the file structure is rewritten (which I believe is inevitable, if we are to support more complex wallpapers), but for now, I left it as it is.

  • ClutterGst (the component allowing video wallpapers) is weird; as soon as I set it a player, there's no way to release it. Because of the OOP structure of the code, deleting any fields (which happens when a wallpaper is switched) would cause internal crashes inside Clutter due to None/null values. Because of it, I had to keep those variables global. It's not pretty, but it's becoming more and more clear that Clutter is a mess (and GTK4 has released already, hooray!), so hopefully when things are moved to GTK this won't be an issue anymore.

  • I faced a problem where the wallpapers and overlays wouldn't be deleted when changing wallpapers, still functioning (and wasting memory) in the background. I eventually found it's because they connect to signals on parent objects (most notably Screen and Bubblemenu), and because of those dangling connections, Python couldn't delete them. I changed some methods, such as a connect_weak on Screen and BubbleMenu, for controlling these signals, and also taking care to manually disconnect every signal I did. I fixed the problem for the wallpapers and overlays, which were the biggest issue, but haven't still figured it out for the Desktop. However, since the memory leak caused by this Overlay is pretty small (I toggled it around 50 times and it only increased by 1MB), it's not very urgent right now. I'll see if I can fix it some time later.


On another topic, I haven't decided what version bump we should do. Do we perform a patch or a minor bump? I've tried to minimize breaking changes, and I believe this doesn't introduce any. However, this is quite the lengthy code to review, and I've had no shortage of bugs to fix during the rewrite. I expect more to crop up that I haven't caught, so in a sense, this could be a breaking change. I don't know, what do you think guys?

@Xoas
Copy link

Xoas commented Jan 31, 2021

Nice, and good job!

@logique233
Copy link

NICE 👍

Copy link

@UltiRequiem UltiRequiem left a comment

Choose a reason for hiding this comment

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

Nice work Bro

komorebi-wallpaper-creator.in Outdated Show resolved Hide resolved
komorebi-wallpaper-creator.in Outdated Show resolved Hide resolved
komorebi/consts.in Outdated Show resolved Hide resolved
komorebi/settings.py Outdated Show resolved Hide resolved
meson.build Outdated Show resolved Hide resolved
Copy link

@FFY00 FFY00 left a comment

Choose a reason for hiding this comment

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

Overall, pretty good. Just some things like using global variables, you should instead use an object instance -- put all state related stuff inside a class.

Formatting is also an issue. Even though Python does accept tabs as the indentation level, everyone uses 4 spaces.

I would recommend you to run flake8 on this and fix the issue. It will give you errors when you are not following standard practice.

.gitignore Outdated Show resolved Hide resolved
komorebi-wallpaper-creator.in Outdated Show resolved Hide resolved
komorebi-wallpaper-creator.in Outdated Show resolved Hide resolved
komorebi.in Outdated Show resolved Hide resolved
komorebi.in Outdated Show resolved Hide resolved
komorebi/settings.py Outdated Show resolved Hide resolved
komorebi/settings.py Outdated Show resolved Hide resolved
komorebi/settings.py Outdated Show resolved Hide resolved
komorebi/utilities.py Outdated Show resolved Hide resolved
komorebi/wallpaper_creator/window.py Outdated Show resolved Hide resolved
@rsubtil rsubtil force-pushed the feature/move-to-python branch from 17e23f9 to 3ba101b Compare February 20, 2021 11:37
Copy link

@ljmf00 ljmf00 left a comment

Choose a reason for hiding this comment

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

minor things, after that, @FFY00 should approve your changes and it's good for me

.flake8 Outdated Show resolved Hide resolved
.vscode/settings.json Outdated Show resolved Hide resolved
meson.build Outdated Show resolved Hide resolved
@rsubtil rsubtil marked this pull request as draft March 11, 2021 16:08
@rsubtil
Copy link
Member Author

rsubtil commented Mar 11, 2021

I will be busy in the next upcoming weeks, so I've marked this as a "draft" until I implement all the changes pending.

@Alice-pleasance-liddell
Copy link

good job, man

@rsubtil rsubtil force-pushed the feature/move-to-python branch 2 times, most recently from b018291 to f401eb0 Compare May 2, 2021 13:36
@rsubtil
Copy link
Member Author

rsubtil commented May 2, 2021

Finally had some time to come back to this. I fixed all the other details pointed out, so this should be ready to merge again.

Regarding installation, I've decided to stick with meson. I feel it's more important to stick to GNOME packaging guidelines than those of Python, since this is a highly "desktop-integrated" application. Coupled with the fact I have zero experience on Python packaging, and also having no time to learn it properly, I leave it for somebody else to implement this if it's really important and desired 🙂

@rsubtil rsubtil marked this pull request as ready for review May 2, 2021 13:46
@rsubtil rsubtil force-pushed the feature/move-to-python branch from f401eb0 to ee33db4 Compare May 8, 2021 16:51
Copy link

@FFY00 FFY00 left a comment

Choose a reason for hiding this comment

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

Good job 😊

.flake8 Outdated
[flake8]
ignore =
W503, # line break before binary operator (follow PEP8 style guide)
E402, # module level import not at top of file (because gi requires to query for versions before importing)
Copy link

Choose a reason for hiding this comment

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

I would add # noqa: E402 to those lines instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

In this particular case it's not pleasant to add to all the affected lines, since I can't move these imports to above the gi.require_versions(...):

gi.require_versions(...)

from gi.repository import Gio, Gtk, GtkClutter, Gdk, Gst, Clutter # noqa: E402

from komorebi.preferences_window import PreferencesWindow # noqa: E402
from komorebi.settings import ConfigKeys, Settings # noqa: E402
import komorebi.utilities # noqa: E402

from komorebi.screen import Screen # noqa: E402
...

But I found a per-file-ignores rule which makes this simpler.

komorebi.py Outdated


def check_desktop_compatible():
return not('wayland' in os.environ.get('XDG_SESSION_TYPE', '') or os.environ.get('WAYLAND_DISPLAY', ''))
Copy link

Choose a reason for hiding this comment

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

This seems weird, are you sure you don't want to do os.environ.get('XDG_SESSION_TYPE') == 'wayland'?

>>> 'wayland' in 'lalalawaylandlalala'
True

Also, the default argument fo os.environ.get can be omitted, because it will fallback to None.

>>> os.environ.get('does-not-exist')
None

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this was one of the first files I started with, so my Python knowledge was still very bad 😛

@rsubtil rsubtil force-pushed the feature/move-to-python branch from ee33db4 to be51be1 Compare May 8, 2021 18:27
@terrarier2111
Copy link

Which parts of the codebase depend on Xorg? If i have time and know which parts of the code i have to look at i may implement Wayland support.

@rsubtil
Copy link
Member Author

rsubtil commented May 9, 2021

@terrarier2111 technically, nothing 😅. You can comment/remove the check preventing Wayland environments to test yourself. I tested on multiple occasions and everything works out of the box, without issues whatsoever.

However, some people have had issues with it. The main one I recall is the bubble menu not working; the right-click doesn't get interpreted by Komorebi, getting handled by Gnome Shell instead. If this is really the case, it's a big issue. But, in my environment, I can't replicate it. It might be because I don't use many features of Komorebi too (I just have a simple wallpaper video without anything else, not even the clock)

If you can test it and confirm everything works well, it would be reassuring 🙂. In any case, there isn't anything in the code that's Xorg exclusive, so there's really not any pointers I can give. If you find issues however, I can point you to possible places to look at.

@terrarier2111
Copy link

terrarier2111 commented May 9, 2021

Okay, that's great :) I will test if it works as soon as this pr gets merged, so glad that it may work and thanks for your work man, i really appreciate it.

@terrarier2111
Copy link

One question don't we have to update the required libs in the README's installing instructions? Because for example we need python3 now and we don't need vala anymore.

@terrarier2111
Copy link

terrarier2111 commented May 9, 2021

I decided to test this pr already, the installation worked but when I tried to start Komorebi, i received this error: https://pastebin.com/ugRXs46K

@rsubtil
Copy link
Member Author

rsubtil commented May 9, 2021

I decided to test this pr already, the installation worked but when I tried to start Komorebi, i received this error: https://pastebin.com/ugRXs46K

Thanks for pointing this out. Apparently when GLib.KeyFile can't find a settings, it returns None and throws exceptions; I though only the former happened. I've fixed this, and took the opportunity to also warn the user for any settings not found.

Also just noticed I forgot to save the autostart property as well, so that's fixed too.

@rsubtil rsubtil force-pushed the feature/move-to-python branch from be51be1 to 9b392f4 Compare May 9, 2021 12:50
@rsubtil
Copy link
Member Author

rsubtil commented May 9, 2021

One question don't we have to update the required libs in the README's installing instructions? Because for example we need python3 now and we don't need vala anymore.

Regarding this, the plan is to do a PR right after this one to bump the version and update instructions, since a release can only be done after this PR is merged.

@terrarier2111
Copy link

New error: https://pastebin.com/8wtxLBn8

@rsubtil
Copy link
Member Author

rsubtil commented May 9, 2021

Oops, my bad 😅

Alright, should be fixed now.

@rsubtil rsubtil force-pushed the feature/move-to-python branch from 9b392f4 to 9234cb0 Compare May 9, 2021 19:10
@terrarier2111
Copy link

I got another one @ev1lbl0w https://pastebin.com/PxT42VNM

@rsubtil
Copy link
Member Author

rsubtil commented May 9, 2021

That problem looks similar to an open issue, though I can't find it now. @Kangie do you remember which one it was? Something like "can't find the default-application-theme for Adwaita theme", if I remember correctly.

Either way, could you open a new issue for it with more info about your setup, please?

Also, does it "crash" komorebi, or does it still run despite the errors?

@terrarier2111
Copy link

I opened a new issue @ev1lbl0w

@Kangie
Copy link
Member

Kangie commented May 13, 2021

So, I somehow missed this. Check it out when I have time!

@lmlask
Copy link

lmlask commented Dec 5, 2021

Any updates? Been a while!

@rsubtil
Copy link
Member Author

rsubtil commented Dec 6, 2021

@lmlask I've been busy in the meantime, but yeah I'd still like this to be merged to continue contributing to komorebi. Just waiting for another review to push.

komorebi.py Outdated
Comment on lines 112 to 114
screen_list = []
for i in range(monitor_count):
screen_list.append(Screen(i))
Copy link

Choose a reason for hiding this comment

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

List comprehension is faster when appending like that than a regular for loop since the compiler generates bytecode specialization for that call.

Suggested change
screen_list = []
for i in range(monitor_count):
screen_list.append(Screen(i))
screen_list = [Screen(i) for i in range(monitor_count)]

It also looks prettier :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, thanks

@rsubtil rsubtil force-pushed the feature/move-to-python branch from 9234cb0 to b30e8f3 Compare December 7, 2021 16:28
@jgabriel98
Copy link

jgabriel98 commented Mar 7, 2022

Just a minor concern: is it a good idea to port to python?
From my understanding komorebi is not lightweight, so using python wouldn't make it even heavier?

@rsubtil
Copy link
Member Author

rsubtil commented Aug 26, 2022

Just a minor concern: is it a good idea to port to python? From my understanding komorebi is not lightweight, so using python wouldn't make it even heavier?

So sorry for the very late reply.

Changing the codebase to Python (or any language for that matter) should have little to no perceptible impact, as most of the times komorebi will be running native GTK/Clutter code. And from my daily usage so far, I never noticed any hitch or hiccup when compared to the original code.

If komorebi is being resource intensive on video wallpapers, it's likely because hardware accelerated video decoding isn't working properly. Check here for some guides on how to check and fix that.

@Ultra980
Copy link

Hi, any updates on this?

@rsubtil
Copy link
Member Author

rsubtil commented Sep 1, 2023

Hi, any updates on this?

See #88.

Regarding this PR, well, at the time it was working, and I did use the project daily for a few months. Right now I'm not using it anymore, so I cannot guarantee this still works, but if you're interested in contributing, and would like to work under this PR work, let me know and I can merge this.

@Kangie
Copy link
Member

Kangie commented Mar 4, 2024

Let's get this merged at least - I can't see any reason not to and there's a far wider python contributor-base.

@Kangie Kangie merged commit 1a68193 into Komorebi-Fork:master Mar 4, 2024
@Kangie Kangie mentioned this pull request Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.