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
Merged
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
20 changes: 20 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

# CI config
[*.{yml,yaml}]
indent_style = space
indent_size = 2

# Python and generated Python source code
[{*.py,komorebi/*.in}]
indent_style = space
indent_size = 4

# Meson build files
[*.build]
indent_style = space
indent_size = 4
7 changes: 7 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[flake8]
ignore =
W503, # line break before binary operator (follow PEP8 style guide)
per-file-ignores =
komorebi.py:E402
komorebi-wallpaper-creator.py:E402
max-line-length = 127
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build
builddir
__pycache__
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"python.linting.flake8Enabled": true,
"python.linting.enabled": true
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ If your issue has not already been reported, please report it [here](https://git

### Thanks To:

Pete Lewis ([@PJayB](https://github.com/PJayB)) for adding multi-monitor support
Pete Lewis ([@PJayB](https://github.com/PJayB)) for adding multi-monitor support
6 changes: 0 additions & 6 deletions config.vala.in

This file was deleted.

75 changes: 75 additions & 0 deletions komorebi-wallpaper-creator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env python3

import argparse
import gi
import logging
import sys
import os

gi.require_versions({
'Clutter': '1.0',
'Gtk': '3.0'
})

from gi.repository import Gtk, Gio

import komorebi
from komorebi.wallpaper_creator.window import WallpaperWindow


def main_parser():
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--version',
action='version',
help='show current version',
version=f'Version: {komorebi.__version__}\nMaintained by: Komorebi Team')
parser.add_argument('-l', '--log',
type=str,
choices=['NORMAL', 'INFO', 'DEBUG'],
default='NORMAL',
help="set logging level for komorebi")
return parser


def main():
print(f'Welcome to {komorebi.__package_name__} Wallpaper Creator')

parser = main_parser()
args = parser.parse_args()

log_level = logging.WARNING
log_format = ''

if args.log:
if args.log == 'INFO':
log_level = logging.INFO
log_format = '[%(levelname)s]: %(message)s'
elif args.log == 'DEBUG':
log_level = logging.DEBUG
log_format = '[%(levelname)s] (%(asctime)s): %(message)s'

logging.basicConfig(format=log_format, level=log_level, datefmt='%H:%M:%S')

# Load resources
resource_path = os.path.join(komorebi.__package_datadir__, 'komorebi.gresource')
resource = Gio.Resource.load(resource_path)
Gio.resources_register(resource)

Gtk.init(sys.argv)
logging.debug('Gtk initialized')

window = WallpaperWindow()

main_settings = Gtk.Settings.get_default()
main_settings.props.gtk_application_prefer_dark_theme = True
main_settings.props.gtk_xft_antialias = 1
main_settings.props.gtk_xft_rgba = "none"
main_settings.props.gtk_xft_hintstyle = "slight"

window.show_all()

Gtk.main()


if __name__ == '__main__':
main()
154 changes: 154 additions & 0 deletions komorebi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/usr/bin/env python3

import argparse
import os
import gi
import signal
import sys
import logging

gi.require_versions({
'Gtk': '3.0',
'GObject': '2.0',
'GtkClutter': '1.0',
'Clutter': '1.0',
'ClutterGst': '3.0',
'Gdk': '3.0',
'GdkPixbuf': '2.0',
'Gst': '1.0',
'WebKit2': '4.0',
})

from gi.repository import Gio, Gtk, GtkClutter, Gdk, Gst, Clutter

from komorebi.preferences_window import PreferencesWindow
from komorebi.settings import ConfigKeys, Settings
import komorebi.utilities

from komorebi.screen import Screen


def check_desktop_compatible():
rsubtil marked this conversation as resolved.
Show resolved Hide resolved
return not(os.environ.get('XDG_SESSION_TYPE') == 'wayland' or os.environ.get('WAYLAND_DISPLAY'))


def main_parser():
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--version',
action='version',
help='show current version',
version=f'Version: {komorebi.__version__}\nMaintained by: Komorebi Team')
parser.add_argument('-ss', '--single-screen',
action='store_true',
help='force komorebi to run only on the main screen')
parser.add_argument('-l', '--log',
type=str,
choices=['NORMAL', 'INFO', 'DEBUG'],
default='NORMAL',
help="set logging level for komorebi")
return parser


def _on_destroy(*args):
logging.info("Quitting...")
Clutter.main_quit()


def main():
print(f'Welcome to {komorebi.__package_name__}')

# Handle Ctrl-C
signal.signal(signal.SIGINT, signal.SIG_DFL)

# Parse the arguments
parser = main_parser()
args = parser.parse_args()

# Setup logger
log_level = logging.WARNING
log_format = '[%(levelname)s]: %(message)s'

if args.log:
if args.log == 'INFO':
log_level = logging.INFO
elif args.log == 'DEBUG':
log_level = logging.DEBUG
log_format = '[%(levelname)s] (%(asctime)s): %(message)s'

logging.basicConfig(format=log_format, level=log_level, datefmt='%H:%M:%S')

# Ensure we are not on Wayland
if not check_desktop_compatible():
logging.error('Wayland detected. Not supported (yet) :(')
logging.info('Contribute to Komorebi and add the support! <3')
return

# Initialize backends
GtkClutter.init(sys.argv)
logging.debug("GtkClutter initialized")

Settings.load_settings()
logging.debug("Configuration file read")

logging.info('loading Gst')
Gst.init(sys.argv)
logging.debug('Gst initialized')

# Load resources
resource_path = os.path.join(komorebi.__package_datadir__, 'komorebi.gresource')
resource = Gio.Resource.load(resource_path)
Gio.resources_register(resource)

display = Gdk.Display.get_default()
if args.single_screen:
monitor_count = 1
else:
monitor_count = display.get_n_monitors()
logging.info(f"Monitor Count - {monitor_count}")

komorebi.utilities.init_clipboard(display)

# Initialize Screen's
screen_list = [Screen(i) for i in range(monitor_count)]

# Setup some GTK properties
main_settings = Gtk.Settings.get_default()
main_settings.props.gtk_application_prefer_dark_theme = True
main_settings.props.gtk_xft_antialias = 1
main_settings.props.gtk_xft_rgba = "none"
main_settings.props.gtk_xft_hintstyle = "slight"

# Setup preferences window
def _on_settings_changed(_, setting_key):
logging.debug("Setting " + str(setting_key) + " changed!")
if setting_key == ConfigKeys.WALLPAPER_NAME:
for screen in screen_list:
screen.load_wallpaper(Settings.wallpaper_name)
elif setting_key == ConfigKeys.AUTOSTART:
komorebi.utilities.toggle_autostart()
else:
for screen in screen_list:
screen.on_settings_changed(setting_key)
return True

prefs_window = PreferencesWindow()
prefs_window.connect('settings-changed', _on_settings_changed)

# Setup screens
def _on_settings_request_event(_, wallpaper_tab):
prefs_window.show(wallpaper_tab)
return True

for screen in screen_list:
screen.connect("destroy", _on_destroy)
screen.load_wallpaper(Settings.wallpaper_name)
screen.fade_in()
screen.connect('settings_requested', _on_settings_request_event)

# Start Clutter backend
logging.debug("Starting Clutter backend...")
Clutter.main()


if __name__ == '__main__':
main()
4 changes: 4 additions & 0 deletions komorebi/__init__.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
__package_name__ = @PACKAGE_NAME@
__version__ = @PACKAGE_VERSION@
__package_datadir__ = @PKGDATADIR@
__datadir__ = @DATADIR@
74 changes: 74 additions & 0 deletions komorebi/bubblemenu/item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import logging
from enum import IntEnum

from gi.repository import Clutter


# View modes for a menu item
class ViewMode(IntEnum):
VISIBLE = 0 # Item is visible and interactive
GREYED = 1 # Item is visible but "greyed" out, can't be interacted with
INVISIBLE = 2 # Item is invisible and doesn't occupy space on the menu


class BubbleMenuItem(Clutter.Text):
# Properties
_view_mode = ViewMode.VISIBLE

def __init__(self, text, callback):
Clutter.Text.__init__(self)
logging.debug(f'Initializing BubbleMenuItem(text="{text}")')

# Setup properties
self.set_x_align(Clutter.ActorAlign.START)
self.set_x_expand(True)
self.set_reactive(False)
self.set_selectable(False)
self.set_margin_top(5)

self.set_font_name('Lato 15')
self.set_text(text)
self.set_color(Clutter.Color.from_string('white')[1])

self.signals_setup()

self.hide()

self.connect_after("button_press_event", callback)
logging.debug('Initialized BubbleMenuItem')

def signals_setup(self):
def _on_button_press_event(self, e):
self.set_opacity(100)
return False

def _on_motion_event(self, e):
self.set_opacity(200)
return True

def _on_leave_event(self, e):
self.set_opacity(255)
return True

self.connect_after("button_press_event", _on_button_press_event)
self.connect_after("motion_event", _on_motion_event)
self.connect_after("leave_event", _on_leave_event)

def show_item(self):
if self._view_mode != ViewMode.INVISIBLE:
self.show()
self.set_opacity(255 if self._view_mode == ViewMode.VISIBLE else 10)
self.set_reactive(self._view_mode == ViewMode.VISIBLE)

def hide_item(self):
self.hide()
self.set_reactive(False)

def set_view_mode(self, view_mode):
self._view_mode = view_mode
if self._view_mode == ViewMode.VISIBLE:
self.set_opacity(255)
elif self._view_mode == ViewMode.GREYED:
self.set_opacity(10)
elif self._view_mode == ViewMode.INVISIBLE:
self.hide()
Loading