Skip to content

Commit

Permalink
Bump version and #123
Browse files Browse the repository at this point in the history
  • Loading branch information
einarf committed Nov 30, 2024
1 parent cbdc8b3 commit 47429fe
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 4 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 3.0.1

* Timers now have `fps` and `fps_average` properties for obtaining the current and average frame rate
* Added `WindowConfig.hidden_window_framerate_limit` limiting framerate when the window is hidden.
The default value is currently 30 fps. This can be disabled by setting the value to 0.
This change combats framerate spikes in the thousands when the window is minimized eating up
battery life and resources.
* `run_window_config` was split into `create_window_config_instance` and `run_window_config_instance`
making customization easier. `run_window_config` will still behave as before.
* Minimized / iconified windows are now framerate capped
* Some doc improvements

## 3.0.0

* All callback functions now has an `on_` prefix meaning existing code will need updating. The old names was somewhat unambiguous and was a source of confusion. It also makes it easier to separate the callback functions from other methods.
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def __getattr__(cls: Any, name: Any) -> MagicMock:
author = "Einar Forselv"

# The short X.Y version
version = "3.0.0"
version = "3.0.1"
# The full version, including alpha/beta/rc tags
release = version

Expand Down
11 changes: 9 additions & 2 deletions moderngl_window/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
General helper functions aiding in the boostrapping of this library.
"""

# pylint: disable = redefined-outer-name, too-few-public-methods
import argparse
import logging
import os
import sys
import time
import weakref
from pathlib import Path
from typing import Any, Optional
Expand All @@ -19,7 +19,7 @@
from moderngl_window.utils.keymaps import AZERTY, QWERTY, KeyMap, KeyMapFactory # noqa
from moderngl_window.utils.module_loading import import_string

__version__ = "3.0.0"
__version__ = "3.0.1"

IGNORE_DIRS = [
"__pycache__",
Expand Down Expand Up @@ -278,6 +278,13 @@ def run_window_config_instance(config: WindowConfig) -> None:
while not window.is_closing:
current_time, delta = timer.next_frame()

# Framerate limit for hidden windows
if not window.visible and config.hidden_window_framerate_limit > 0:
expected_delta_time = 1.0 / config.hidden_window_framerate_limit
sleep_time = expected_delta_time - delta
if sleep_time > 0:
time.sleep(sleep_time)

if config.clear_color is not None:
window.clear(*config.clear_color)

Expand Down
11 changes: 11 additions & 0 deletions moderngl_window/context/base/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,17 @@ def on_key_event(self, key, action, modifiers):
# Default value
resource_dir = None
"""
hidden_window_framerate_limit = 30
"""
The framerate limit for hidden windows. This is useful for windows that
should not render at full speed when hidden. On some platforms the
render loop can spike to thousands of frames per second when hidden
eating up battery life on laptops.
A value less than 0 will disable the framerate limit. Otherwise the
the value is a suggested limit in frames per second.
"""

log_level = logging.INFO
"""
Sets the log level for this library using the standard `logging` module.
Expand Down
1 change: 1 addition & 0 deletions moderngl_window/context/glfw/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ def glfw_window_iconify(self, window: Any, iconified: int) -> None:
window: The window
iconified (int): 1 = minimized, 0 = restored.
"""
self._visible = iconified == 0
self._iconify_func(True if iconified == 1 else False)

def glfw_window_close(self, window: Any) -> None:
Expand Down
2 changes: 2 additions & 0 deletions moderngl_window/context/pygame2/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,10 @@ def process_events(self) -> None:
# Window iconify state
if getattr(event, "state", None) == 2:
if event.gain:
self._visible = True
self._iconify_func(False)
else:
self._visible = False
self._iconify_func(True)

# This is also a problem on linux, but is too disruptive during resize events
Expand Down
2 changes: 2 additions & 0 deletions moderngl_window/context/pyglet/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,12 @@ def on_close(self) -> None:

def on_show(self) -> None:
"""Called when window first appear or restored from hidden state"""
self._visible = True
self._iconify_func(False)

def on_hide(self) -> None:
"""Called when window is minimized"""
self._visible = False
self._iconify_func(True)

def on_file_drop(self, x: int, y: int, paths: list[Union[str, Path]]) -> None:
Expand Down
2 changes: 2 additions & 0 deletions moderngl_window/context/pyqt5/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,12 @@ def close(self) -> None:

def show_event(self, event: QtCore.QEvent) -> None:
"""The standard Qt show event"""
self._visible = True
self._iconify_func(False)

def hide_event(self, event: QtCore.QEvent) -> None:
"""The standard Qt hide event"""
self._visible = False
self._iconify_func(True)

def destroy(self) -> None:
Expand Down
2 changes: 2 additions & 0 deletions moderngl_window/context/pyside2/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,10 +361,12 @@ def close(self) -> None:

def show_event(self, event: QtCore.QEvent) -> None:
"""The standard Qt show event"""
self._visible = True
self._iconify_func(False)

def hide_event(self, event: QtCore.QEvent) -> None:
"""The standard Qt hide event"""
self._visible = False
self._iconify_func(True)

def destroy(self) -> None:
Expand Down
2 changes: 2 additions & 0 deletions moderngl_window/context/sdl2/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,10 @@ def process_events(self) -> None:
]:
self.resize(event.window.data1, event.window.data2)
elif event.window.event == sdl2.SDL_WINDOWEVENT_MINIMIZED:
self._visible = False
self._iconify_func(True)
elif event.window.event == sdl2.SDL_WINDOWEVENT_RESTORED:
self._visible = True
self._iconify_func(False)

def close(self) -> None:
Expand Down
2 changes: 2 additions & 0 deletions moderngl_window/context/tk/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,11 @@ def tk_close_window(self) -> None:
self._close = True

def tk_map(self, event: tkinter.Event) -> None:
self._visible = True
self._iconify_func(False)

def tk_unmap(self, event: tkinter.Event) -> None:
self._visible = False
self._iconify_func(True)

def destroy(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "moderngl-window"
version = "3.0.0"
version = "3.0.1"
description = "A cross platform helper library for ModernGL making window creation and resource loading simple"
readme = "README.md"
authors = [{ name = "Einar Forselv", email = "[email protected]" }]
Expand Down

0 comments on commit 47429fe

Please sign in to comment.