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

Upgrade to SDL3 #1332

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
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
4 changes: 2 additions & 2 deletions extra/requirements_linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Pillow
PlexAPI
PyGObject
pylast>=3.1.0
PySDL2
pysdl2-dll
PySDL3
#pysdl3-dll
requests
Send2Trash
unidecode
4 changes: 2 additions & 2 deletions extra/requirements_macos.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Pillow
PlexAPI
PyGObject
pylast>=3.1.0
PySDL2
pysdl2-dll
PySDL3
#pysdl3-dll
requests
Send2Trash
unidecode
4 changes: 2 additions & 2 deletions extra/requirements_windows.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ PlexAPI
PyGObject
pyinstaller
pylast>=3.1.0
PySDL2
pysdl2-dll
PySDL3
#pysdl3-dll
requests
Send2Trash
unidecode
2 changes: 1 addition & 1 deletion linux.spec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ a = Analysis(
("src/tauon/theme", "theme"),
("src/tauon/templates", "templates"),
# This could only have SDL2.framework and SDL2_image.framework to save space...
(f".venv/lib/python{python_ver}/site-packages/sdl2dll/dll", "sdl2dll/dll"),
# (f".venv/lib/python{python_ver}/site-packages/sdl2dll/dll", "sdl2dll/dll"),
# (f".venv/lib/python{python_ver}/site-packages/sdl2dll/dll/SDL2.framework", "sdl2dll/dll/SDL2.framework"),
# (f".venv/lib/python{python_ver}/site-packages/sdl2dll/dll/SDL2_image.framework", "sdl2dll/dll/SDL2_image.framework"),
],
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Pillow # ; sys_platform != 'darwin' # Install Pillow from b
PlexAPI
PyGObject
pylast>=3.1.0
PySDL2
pysdl2-dll # Don't rely on system SDL2 https://github.com/py-sdl/py-sdl2#requirements
PySDL3
#pysdl3-dll # Don't rely on system SDL2 https://github.com/py-sdl/py-sdl2#requirements
#python-magic # optional
requests
Send2Trash
Expand Down
161 changes: 62 additions & 99 deletions src/tauon/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,47 +20,11 @@
import os
import pickle
import sys
from ctypes import c_int, pointer
from ctypes import c_int, pointer, c_float, byref
from pathlib import Path

from gi.repository import GLib
from sdl2 import (
SDL_BLENDMODE_BLEND,
SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,
SDL_HINT_RENDER_SCALE_QUALITY,
SDL_HINT_VIDEO_ALLOW_SCREENSAVER,
SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,
SDL_INIT_VIDEO,
SDL_MESSAGEBOX_ERROR,
SDL_RENDERER_ACCELERATED,
SDL_RENDERER_PRESENTVSYNC,
SDL_WINDOW_ALLOW_HIGHDPI,
SDL_WINDOW_BORDERLESS,
SDL_WINDOW_FULLSCREEN_DESKTOP,
SDL_WINDOW_HIDDEN,
SDL_WINDOW_RESIZABLE,
SDL_WINDOWPOS_UNDEFINED,
SDL_CreateRenderer,
SDL_CreateTextureFromSurface,
SDL_CreateWindow,
SDL_DestroyTexture,
SDL_FreeSurface,
SDL_GetError,
SDL_GetWindowSize,
SDL_GL_GetDrawableSize,
SDL_Init,
SDL_MaximizeWindow,
SDL_Rect,
SDL_RenderClear,
SDL_RenderCopy,
SDL_RenderPresent,
SDL_SetHint,
SDL_SetRenderDrawBlendMode,
SDL_SetRenderDrawColor,
SDL_SetWindowOpacity,
SDL_ShowSimpleMessageBox,
)
from sdl2.sdlimage import IMG_Load
import sdl3

install_directory: Path = Path(__file__).resolve().parent
sys.path.append(str(install_directory.parent))
Expand Down Expand Up @@ -105,7 +69,6 @@

logging.info(f"{t_title} {t_version}")
logging.info("Copyright 2015-2025 Taiko2k [email protected]\n")
logging.info("Arguments: " + " ".join(sys.argv))

# Early arg processing
def transfer_args_and_exit() -> None:
Expand Down Expand Up @@ -236,11 +199,10 @@ def transfer_args_and_exit() -> None:
if sys.platform == "win32" and sys.getwindowsversion().major < 10 or Path(user_directory / "nohidpi").is_file():
allow_hidpi = False

SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, b"1")
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, b"1")
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, b"0")
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best".encode())
# SDL_SetHint(b"SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR", b"0")
sdl3.SDL_SetHint(sdl3.SDL_HINT_VIDEO_ALLOW_SCREENSAVER.encode(), b"1")
sdl3.SDL_SetHint(sdl3.SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH.encode(), b"1")
sdl3.SDL_SetHint(sdl3.SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR.encode(), b"0")
# sdl3.SDL_SetHint(b"SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR", b"0")

draw_border = True
w = 1120
Expand Down Expand Up @@ -307,45 +269,44 @@ def transfer_args_and_exit() -> None:
if Path(user_directory / "x11").exists():
os.environ["SDL_VIDEODRIVER"] = "x11"

SDL_Init(SDL_INIT_VIDEO)
err = SDL_GetError()

sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO | sdl3.SDL_INIT_EVENTS)

err = sdl3.SDL_GetError()
if err and "GLX" in err.decode():
logging.error(f"SDL init error: {err.decode()}")
SDL_ShowSimpleMessageBox(
SDL_MESSAGEBOX_ERROR, b"Tauon Music Box failed to start :(",
sdl3.SDL_ShowSimpleMessageBox(
sdl3.SDL_MESSAGEBOX_ERROR, b"Tauon Music Box failed to start :(",
b"Error: " + err + b".\n If you're using Flatpak, try run `$ flatpak update`", None)
sys.exit(1)

window_title = t_title
window_title = window_title.encode("utf-8")

flags = SDL_WINDOW_RESIZABLE

if allow_hidpi:
flags |= SDL_WINDOW_ALLOW_HIGHDPI
flags = sdl3.SDL_WINDOW_RESIZABLE | sdl3.SDL_WINDOW_TRANSPARENT

if draw_border and not fs_mode:
flags |= SDL_WINDOW_BORDERLESS
flags |= sdl3.SDL_WINDOW_BORDERLESS

if fs_mode:
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP
flags |= sdl3.SDL_WINDOW_FULLSCREEN_DESKTOP

if old_window_position is None:
o_x = SDL_WINDOWPOS_UNDEFINED
o_y = SDL_WINDOWPOS_UNDEFINED
o_x = sdl3.SDL_WINDOWPOS_UNDEFINED
o_y = sdl3.SDL_WINDOWPOS_UNDEFINED
else:
o_x = old_window_position[0]
o_y = old_window_position[1]

if "--tray" in sys.argv:
flags |= SDL_WINDOW_HIDDEN
flags |= sdl3.SDL_WINDOW_HIDDEN


t_window = SDL_CreateWindow(
t_window = sdl3.SDL_CreateWindow( # todo use SDL_CreateWindowAndRenderer()
window_title,
o_x, o_y,
# o_x, o_y,
logical_size[0], logical_size[1],
flags) # | SDL_WINDOW_FULLSCREEN)
flags)

if not t_window:
logging.error("ERROR CREATING WINDOW!")
Expand All @@ -355,52 +316,45 @@ def transfer_args_and_exit() -> None:
logging.error(f"Size 0: {logical_size[0]}")
logging.error(f"Size 1: {logical_size[1]}")
logging.error(f"Flags: {flags}")
sdl_err = SDL_GetError().decode()
logging.error(f"SDL Error: {sdl_err}")
if sdl_err == "x11 not available":
x11_path = user_directory / "x11"
if x11_path.exists():
logging.critical("Disabled Xwayland preference as X11 was not found - Known issue if on Flatpak - https://github.com/Taiko2k/Tauon/issues/1034")
x11_path.unlink()
os.environ["SDL_VIDEODRIVER"] = "wayland"
t_window = SDL_CreateWindow(
window_title,
o_x, o_y,
logical_size[0], logical_size[1],
flags)
if not t_window:
logging.error(f"Failed to create Wayland fallback window - SDL Error: {SDL_GetError()}")
sys.exit(1)
else:
logging.critical(f"Failed to find {x11_path} but got 'x11 not available' error, hm?")
sys.exit(1)
else:
sys.exit(1)
logging.error(f"SDL Error: {sdl3.SDL_GetError()}")
sys.exit(1)

if maximized:
SDL_MaximizeWindow(t_window)
sdl3.SDL_MaximizeWindow(t_window)

renderer = SDL_CreateRenderer(t_window, 0, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)
drivers = []
i = 0
while True:
x = sdl3.SDL_GetRenderDriver(i)
i += 1
if x is None:
break
drivers.append(x)

logging.debug(f"SDL availiable drivers: {drivers}")

renderer = sdl3.SDL_CreateRenderer(t_window, b"opengl") # sdl3.SDL_RENDERER_PRESENTVSYNC

if not renderer:
logging.error("ERROR CREATING RENDERER!")
logging.error(f"SDL Error: {SDL_GetError()}")
sys.exit(1)

SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND)
SDL_SetWindowOpacity(t_window, window_opacity)
sdl3.SDL_SetRenderDrawBlendMode(renderer, sdl3.SDL_BLENDMODE_BLEND)
sdl3.SDL_SetWindowOpacity(t_window, window_opacity)

SDL_SetRenderDrawColor(renderer, 7, 7, 7, 255)
SDL_RenderClear(renderer)
sdl3.SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0)
sdl3.SDL_RenderClear(renderer)

logging.info(f"SDL window system: {sdl3.SDL_GetCurrentVideoDriver().decode()}")

i_x = pointer(c_int(0))
i_y = pointer(c_int(0))
SDL_GL_GetDrawableSize(t_window, i_x, i_y)
sdl3.SDL_GetWindowSizeInPixels(t_window, i_x, i_y)
window_size[0] = i_x.contents.value
window_size[1] = i_y.contents.value

SDL_GetWindowSize(t_window, i_x, i_y)
sdl3.SDL_GetWindowSize(t_window, i_x, i_y)
logical_size[0] = i_x.contents.value
logical_size[1] = i_y.contents.value

Expand All @@ -414,18 +368,26 @@ def transfer_args_and_exit() -> None:
img_path = img_path2
del img_path2

raw_image = IMG_Load(str(img_path).encode())
sdl_texture = SDL_CreateTextureFromSurface(renderer, raw_image)
w = raw_image.contents.w
h = raw_image.contents.h
rect = SDL_Rect(window_size[0] // 2 - w // 2, window_size[1] // 2 - h // 2, w, h)
sdl3.SDL_SetRenderDrawColor(renderer, 7, 7, 7, 255)
sdl3.SDL_RenderFillRect(renderer, None)

raw_image = sdl3.IMG_Load(str(img_path).encode())
texture = sdl3.SDL_CreateTextureFromSurface(renderer, raw_image)
i_x = c_float(0.0)
i_y = c_float(0.0)
sdl3.SDL_GetTextureSize(texture, byref(i_x), byref(i_y))
w = i_x.value
h = i_y.value
rect = sdl3.SDL_FRect(window_size[0] // 2 - w // 2, window_size[1] // 2 - h // 2, w, h)
sdl3.SDL_RenderTexture(renderer, texture, None, rect)

SDL_RenderCopy(renderer, sdl_texture, None, rect)

SDL_RenderPresent(renderer)

SDL_FreeSurface(raw_image)
SDL_DestroyTexture(sdl_texture)

sdl3.SDL_RenderPresent(renderer)

sdl3.SDL_DestroySurface(raw_image)
sdl3.SDL_DestroyTexture(texture)

holder = t_bootstrap.holder
holder.t_window = t_window
Expand Down Expand Up @@ -455,13 +417,14 @@ def transfer_args_and_exit() -> None:
holder.log = log

del raw_image
del sdl_texture
del texture
del w
del h
del rect
del flags
del img_path


def main() -> None:
"""Launch Tauon by means of importing t_main.py"""
from tauon.t_modules import t_main
Expand Down
Loading
Loading