Compare commits

..

8 Commits

Author SHA1 Message Date
Tyler Goodlet 74fcf8ec25 Reorder imports in `qt_screen_info.py` ??
For wtv reason on nixos importing `pyqtgraph` first is causing `numpy`
to fail import?? No idea, but likely something to do with recent
`flake.nix`'s ld-lib-linking with `<nixpkgs>` marlarky?
2025-12-16 18:22:05 -05:00
Tyler Goodlet b8fe866826 binance: handle new `TRADIFI_PERPETUAL`.. 2025-12-16 16:20:42 -05:00
Tyler Goodlet e0178f45aa Update `default.nix` (from @nt) for py313 2025-12-16 16:20:42 -05:00
Tyler Goodlet 5e550e18a9 nix: make Qt6 work on wayland
Taking many tips from our `default.nix` (thanks @nt!) this seems to be
the minimal overlay required for a flake to get up and running with
`piker chart` B)

Notes,
- for now, we're pinning to a major `cpython` version (3.13)
- ensure we (can) build with `nixpkgs.qt6.qtwayland`
- add the minimal Qt ld-lib-path linkings including those for plugin
  use (required for wayland mode).
- for now, hardcode "wayland" platform-mode and the linux standard
  "xdg-shell" integration.
- leave some TODOs to better parameterize around py versions.
2025-12-16 16:20:42 -05:00
Tyler Goodlet 944740799c Touch `conf.toml` by default when dne? 2025-12-16 16:20:42 -05:00
Tyler Goodlet 4e7fd0879c Bump `flake.lock`, seemly nicely minimized B) 2025-12-16 16:20:42 -05:00
Tyler Goodlet b2fe31bfc6 Redo `flake.nix` using `pyproject.nix` recos
Particularly using their recommended "impure template",
- https://pyproject-nix.github.io/pyproject.nix/templates.html#impure
- code: https://github.com/pyproject-nix/pyproject.nix/blob/master/templates/impure/flake.nix

Note the `shellHook` now contains various `uv`-specific osenv settings
and cmds to get a dev-env setup the way i would do it by default, that
includes all dev and extra (group) deps. For now i've hard coded the
"virt-env subdir" used by `uv` to match the cpython version. We can
obviously parameterize this much better in the future.

For those who want to spawn a diff shell then bash see the commented
line, for ex. i personally use `nix develop -c uv run xonsh`.
2025-12-16 16:20:42 -05:00
Tyler Goodlet d4fe6b7717 Don't pin `pendulum` version so we can use wheel
Bump version in lock file to match.
2025-12-16 16:20:42 -05:00
4 changed files with 20 additions and 113 deletions

View File

@ -104,9 +104,6 @@ class Pair(Struct, frozen=True, kw_only=True):
# https://developers.binance.com/docs/binance-spot-api-docs#future-changes # https://developers.binance.com/docs/binance-spot-api-docs#future-changes
pegInstructionsAllowed: bool = False pegInstructionsAllowed: bool = False
# https://developers.binance.com/docs/binance-spot-api-docs#2025-12-02
opoAllowed: bool = False
filters: dict[ filters: dict[
str, str,
str | int | float, str | int | float,

View File

@ -184,25 +184,22 @@ class DpiAwareFont:
self._font_inches = inches self._font_inches = inches
font_size = math.floor(inches * pdpi) font_size = math.floor(inches * pdpi)
ftype: str = f'{type(self)!r}' log.debug(
log.info( f"screen:{screen.name()}\n"
f'screen: {screen.name()}\n' f"pDPI: {pdpi}, lDPI: {ldpi}, scale: {scale}\n"
f'pDPI: {pdpi!r}\n' f"\nOur best guess font size is {font_size}\n"
f'lDPI: {ldpi!r}\n'
f'scale: {scale!r}\n'
f'{ftype}._font_inches={self._font_inches!r}\n'
f'\n'
f"Our best guess for an auto-font-size is,\n"
f'font_size: {font_size!r}\n'
) )
# apply the size # apply the size
self._set_qfont_px_size(font_size) self._set_qfont_px_size(font_size)
def boundingRect(self, value: str) -> QtCore.QRectF: def boundingRect(self, value: str) -> QtCore.QRectF:
if (screen := self.screen) is None:
screen = self.screen
if screen is None:
raise RuntimeError("You must call .configure_to_dpi() first!") raise RuntimeError("You must call .configure_to_dpi() first!")
unscaled_br: QtCore.QRectF = self._qfm.boundingRect(value) unscaled_br = self._qfm.boundingRect(value)
return QtCore.QRectF( return QtCore.QRectF(
0, 0,
0, 0,

View File

@ -1,64 +0,0 @@
#!env xonsh
'''
Compute the pxs-per-inch (PPI) naively for the local DE.
NOTE, currently this only supports the `sway`-TWM on wayland.
!TODO!
- [ ] support Xorg (and possibly other OSs as well?
- [ ] conver this to pure py code, dropping the `.xsh` specifics
instead for `subprocess` API calls?
- [ ] possibly unify all this with `./qt_screen_info.py` as part of
a "PPI config wizard" or something, but more then likely we'll
have lib-ified version inside modden/piker by then?
'''
import math
import json
# XXX, xonsh part using "subprocess mode"
disp_infos: list[dict] = json.loads($(wlr-randr --json))
lappy: dict = disp_infos[0]
dims: dict[str, int] = lappy['physical_size']
w_cm: int = dims['width']
h_cm: int = dims['height']
# cm per inch
cpi: float = 25.4
# compute "diagonal" size (aka hypot)
diag_inches: float = math.sqrt((h_cm/cpi)**2 + (w_cm/cpi)**2)
# compute reso-hypot / inches-hypot
hi_res: dict[str, float|bool] = lappy['modes'][0]
w_px: int = hi_res['width']
h_px: int = hi_res['height']
diag_pxs: float = math.sqrt(h_px**2 + w_px**2)
unscaled_ppi: float = diag_pxs/diag_inches
# retrieve TWM info on the display (including scaling info)
sway_disp_info: dict = json.loads($(swaymsg -r -t get_outputs))[0]
scale: float = sway_disp_info['scale']
print(
f'output: {sway_disp_info["name"]!r}\n'
f'--- DIMENSIONS ---\n'
f'w_cm: {w_cm!r}\n'
f'h_cm: {h_cm!r}\n'
f'w_px: {w_px!r}\n'
f'h_cm: {h_px!r}\n'
f'\n'
f'--- DIAGONALS ---\n'
f'diag_inches: {diag_inches!r}\n'
f'diag_pxs: {diag_pxs!r}\n'
f'\n'
f'--- PPI-related-info ---\n'
f'(DE reported) scale: {scale!r}\n'
f'unscaled PPI: {unscaled_ppi!r}\n'
f'|_ =sqrt(h_px**2 + w_px**2) / sqrt(h_in**2 + w_in**2)\n'
f'scaled PPI: {unscaled_ppi/scale!r}\n'
f'|_ =unscaled_ppi/scale\n'
)

View File

@ -31,7 +31,6 @@ Resource list for mucking with DPIs on multiple screens:
- https://doc.qt.io/qt-5/qguiapplication.html#screenAt - https://doc.qt.io/qt-5/qguiapplication.html#screenAt
''' '''
import os
from PyQt6 import ( from PyQt6 import (
QtCore, QtCore,
@ -45,12 +44,6 @@ from PyQt6.QtCore import (
) )
from pyqtgraph import QtGui from pyqtgraph import QtGui
# https://doc.qt.io/qt-6/highdpi.html#environment-variable-reference
os.environ['QT_USE_PHYSICAL_DPI'] = '0'
# TODO? i don't get how this is useful, when i set it it seems
# the physical-dpi get's computed incorrectly??
# Proper high DPI scaling is available in Qt >= 5.6.0. This attibute # Proper high DPI scaling is available in Qt >= 5.6.0. This attibute
# must be set before creating the application # must be set before creating the application
if hasattr(Qt, 'AA_EnableHighDpiScaling'): if hasattr(Qt, 'AA_EnableHighDpiScaling'):
@ -65,22 +58,13 @@ if hasattr(Qt, 'AA_UseHighDpiPixmaps'):
True, True,
) )
# NOTE, inherits `QGuiApplication`
# https://doc.qt.io/qt-6/qapplication.html
# https://doc.qt.io/qt-6/qguiapplication.html
app = QtWidgets.QApplication([]) app = QtWidgets.QApplication([])
#
# ^TODO? various global DPI settings?
# [ ] DPI rounding policy,
# - https://doc.qt.io/qt-6/qt.html#HighDpiScaleFactorRoundingPolicy-enum
# - https://doc.qt.io/qt-6/qguiapplication.html#setHighDpiScaleFactorRoundingPolicy
window = QtWidgets.QMainWindow() window = QtWidgets.QMainWindow()
main_widget = QtWidgets.QWidget() main_widget = QtWidgets.QWidget()
window.setCentralWidget(main_widget) window.setCentralWidget(main_widget)
window.show() window.show()
_main_pxr: float = main_widget.devicePixelRatioF() pxr: float = main_widget.devicePixelRatioF()
# explicitly get main widget and primary displays # explicitly get main widget and primary displays
current_screen: QtGui.QScreen = app.screenAt( current_screen: QtGui.QScreen = app.screenAt(
@ -93,13 +77,7 @@ for screen in app.screens():
name: str = screen.name() name: str = screen.name()
model: str = screen.model().rstrip() model: str = screen.model().rstrip()
size: QSize = screen.size() size: QSize = screen.size()
geo: QRect = screen.geometry() geo: QRect = screen.availableGeometry()
# device-pixel-ratio
# https://doc.qt.io/qt-6/highdpi.html
pxr: float = screen.devicePixelRatio()
unscaled_size: QSize = pxr * size
phydpi: float = screen.physicalDotsPerInch() phydpi: float = screen.physicalDotsPerInch()
logdpi: float = screen.logicalDotsPerInch() logdpi: float = screen.logicalDotsPerInch()
is_primary: bool = screen is primary_screen is_primary: bool = screen is primary_screen
@ -110,12 +88,11 @@ for screen in app.screens():
f'|_primary: {is_primary}\n' f'|_primary: {is_primary}\n'
f' _current: {is_current}\n' f' _current: {is_current}\n'
f' _model: {model}\n' f' _model: {model}\n'
f' _size: {size}\n' f' _screen size: {size}\n'
f' _geometry: {geo}\n' f' _screen geometry: {geo}\n'
f' _devicePixelRatio(): {pxr}\n' f' _devicePixelRationF(): {pxr}\n'
f' _unscaled-size: {unscaled_size!r}\n' f' _physical dpi: {phydpi}\n'
f' _physical-dpi: {phydpi}\n' f' _logical dpi: {logdpi}\n'
f' _logical-dpi: {logdpi}\n'
) )
# app-wide font info # app-wide font info
@ -133,8 +110,8 @@ str_w: int = str_br.width()
print( print(
f'------ global font settings ------\n' f'------ global font settings ------\n'
f'font dpi: {fontdpi!r}\n' f'font dpi: {fontdpi}\n'
f'font height: {font_h!r}\n' f'font height: {font_h}\n'
f'string bounding rect: {str_br!r}\n' f'string bounding rect: {str_br}\n'
f'string width : {str_w!r}\n' f'string width : {str_w}\n'
) )