os_window_size.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #!/usr/bin/env python
  2. # License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
  3. from typing import Any, Callable, Dict, NamedTuple, Optional, Tuple, Union
  4. from .constants import is_macos, is_wayland
  5. from .fast_data_types import get_options
  6. from .options.types import Options
  7. from .types import FloatEdges
  8. from .typing import EdgeLiteral
  9. from .utils import log_error
  10. class WindowSize(NamedTuple):
  11. size: int
  12. unit: str
  13. class WindowSizes(NamedTuple):
  14. width: WindowSize
  15. height: WindowSize
  16. class WindowSizeData(NamedTuple):
  17. initial_window_sizes: WindowSizes
  18. remember_window_size: bool
  19. single_window_margin_width: FloatEdges
  20. window_margin_width: FloatEdges
  21. single_window_padding_width: FloatEdges
  22. window_padding_width: FloatEdges
  23. def sanitize_window_size(x: Any) -> int:
  24. ans = int(x)
  25. return max(20, min(ans, 50000))
  26. def edge_spacing(which: EdgeLiteral, opts:Optional[Union[WindowSizeData, Options]] = None) -> float:
  27. if opts is None:
  28. opts = get_options()
  29. margin: float = getattr(opts.single_window_margin_width, which)
  30. if margin < 0:
  31. margin = getattr(opts.window_margin_width, which)
  32. padding: float = getattr(opts.single_window_padding_width, which)
  33. if padding < 0:
  34. padding = getattr(opts.window_padding_width, which)
  35. return float(padding + margin)
  36. def initial_window_size_func(opts: WindowSizeData, cached_values: Dict[str, Any]) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]:
  37. if 'window-size' in cached_values and opts.remember_window_size:
  38. ws = cached_values['window-size']
  39. try:
  40. w, h = map(sanitize_window_size, ws)
  41. def initial_window_size(*a: Any) -> Tuple[int, int]:
  42. return w, h
  43. return initial_window_size
  44. except Exception:
  45. log_error('Invalid cached window size, ignoring')
  46. w, w_unit = opts.initial_window_sizes.width
  47. h, h_unit = opts.initial_window_sizes.height
  48. def get_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> Tuple[int, int]:
  49. if not is_macos and not is_wayland():
  50. # Not sure what the deal with scaling on X11 is
  51. xscale = yscale = 1
  52. def effective_margin(which: EdgeLiteral) -> float:
  53. ans: float = getattr(opts.single_window_margin_width, which)
  54. if ans < 0:
  55. ans = getattr(opts.window_margin_width, which)
  56. return ans
  57. def effective_padding(which: EdgeLiteral) -> float:
  58. ans: float = getattr(opts.single_window_padding_width, which)
  59. if ans < 0:
  60. ans = getattr(opts.window_padding_width, which)
  61. return ans
  62. if w_unit == 'cells':
  63. spacing = effective_margin('left') + effective_margin('right')
  64. spacing += effective_padding('left') + effective_padding('right')
  65. width = cell_width * w / xscale + (dpi_x / 72) * spacing + 1
  66. else:
  67. width = w
  68. if h_unit == 'cells':
  69. spacing = effective_margin('top') + effective_margin('bottom')
  70. spacing += effective_padding('top') + effective_padding('bottom')
  71. height = cell_height * h / yscale + (dpi_y / 72) * spacing + 1
  72. else:
  73. height = h
  74. return int(width), int(height)
  75. return get_window_size