python-libei 0.7.0__tar.gz → 0.8.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {python_libei-0.7.0 → python_libei-0.8.1}/PKG-INFO +17 -7
  2. {python_libei-0.7.0 → python_libei-0.8.1}/README.md +16 -6
  3. {python_libei-0.7.0 → python_libei-0.8.1}/pyproject.toml +1 -1
  4. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/__init__.py +1 -1
  5. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/_capi/libei.py +7 -1
  6. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/ei.py +5 -3
  7. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/eis.py +21 -5
  8. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/portal.py +357 -36
  9. {python_libei-0.7.0 → python_libei-0.8.1}/src/python_libei.egg-info/PKG-INFO +17 -7
  10. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_documentation_shape.py +12 -1
  11. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_inputcapture.py +335 -4
  12. python_libei-0.8.1/tests/test_integration_socketpair.py +306 -0
  13. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_portal.py +184 -0
  14. python_libei-0.7.0/tests/test_integration_socketpair.py +0 -125
  15. {python_libei-0.7.0 → python_libei-0.8.1}/LICENSE +0 -0
  16. {python_libei-0.7.0 → python_libei-0.8.1}/setup.cfg +0 -0
  17. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/_capi/__init__.py +0 -0
  18. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/_capi/libeis.py +0 -0
  19. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/_capi/liboeffis.py +0 -0
  20. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/_capi/loader.py +0 -0
  21. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/_cobject.py +0 -0
  22. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/oeffis.py +0 -0
  23. {python_libei-0.7.0 → python_libei-0.8.1}/src/libei/py.typed +0 -0
  24. {python_libei-0.7.0 → python_libei-0.8.1}/src/python_libei.egg-info/SOURCES.txt +0 -0
  25. {python_libei-0.7.0 → python_libei-0.8.1}/src/python_libei.egg-info/dependency_links.txt +0 -0
  26. {python_libei-0.7.0 → python_libei-0.8.1}/src/python_libei.egg-info/requires.txt +0 -0
  27. {python_libei-0.7.0 → python_libei-0.8.1}/src/python_libei.egg-info/top_level.txt +0 -0
  28. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_abi.py +0 -0
  29. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_cobject.py +0 -0
  30. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_documented_examples.py +0 -0
  31. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_ei_objects.py +0 -0
  32. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_eis_objects.py +0 -0
  33. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_event_accessors.py +0 -0
  34. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_integration_extras.py +0 -0
  35. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_integration_frame.py +0 -0
  36. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_integration_lifetime.py +0 -0
  37. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_loader.py +0 -0
  38. {python_libei-0.7.0 → python_libei-0.8.1}/tests/test_oeffis.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-libei
3
- Version: 0.7.0
3
+ Version: 0.8.1
4
4
  Summary: Inject, receive and capture input on Wayland from Python: ctypes bindings for libei, libeis and liboeffis, plus the RemoteDesktop and InputCapture portals
5
5
  Author: Dennis K. Paulsen
6
6
  License-Expression: MIT
@@ -175,7 +175,7 @@ and why, is in
175
175
 
176
176
  ## Status
177
177
 
178
- Beta (`0.7.0`), published on [PyPI](https://pypi.org/project/python-libei/)
178
+ Beta (`0.8.1`), published on [PyPI](https://pypi.org/project/python-libei/)
179
179
  since `0.1.0`, and **the API is not frozen** — expect renames before 1.0.
180
180
 
181
181
  The injection path is exercised end to end against the real libraries by the
@@ -228,17 +228,27 @@ Exactly what was run, when, and against which versions:
228
228
 
229
229
  | Needs | For |
230
230
  | --- | --- |
231
- | 1.1 | `Region.mapping_id`, `Region.convert_point()`, `Device.region_at()` |
231
+ | 1.1 | `Region.mapping_id`, `Device.region_at()` |
232
232
  | 1.4 | ping/pong round trips (`Context.new_ping()`), `Context.disconnect()`, touch cancellation (`Touch.cancel()`) |
233
233
  | 1.5 | `eis.Client.pid` |
234
234
  | 1.6 | `Device.text_utf8()` / `text_keysym()` and TEXT events, `Seat.request_device()`, `Eis.set_flag()` |
235
235
 
236
236
  Nothing is resolved until it is called, so a build without one of these
237
237
  costs you only that call — it raises `LibraryNotFoundError` naming the
238
- missing symbol, while the rest of the package keeps working. The one
239
- exception is `Event.touch_up_event`, which degrades instead of raising:
240
- on libei older than 1.4 it reports `is_cancel=False`, since a library
241
- with no notion of cancellation genuinely never sends one.
238
+ missing symbol, while the rest of the package keeps working. Two
239
+ accessors degrade instead of raising, because every supported version
240
+ exports the symbol and only the answer changed — so there is nothing to
241
+ resolve and nothing to report:
242
+
243
+ - `Event.touch_up_event` reports `is_cancel=False` on libei older than
244
+ 1.4, since a library with no notion of cancellation genuinely never
245
+ sends one.
246
+ - `eis.Event.emulating_sequence` reads 0 on libei older than 1.6
247
+ whatever the client sent: libeis queued the start_emulating event
248
+ without ever copying the sequence into it, until 1.6.0 added the
249
+ missing assignment. A 0 on an older build is indistinguishable from a
250
+ client that really sent 0. The client-side
251
+ `ei.Event.emulating_sequence` is unaffected.
242
252
 
243
253
  These versions were established by building libei 1.2.1 and diffing its
244
254
  exported symbols against every binding here, not by reading `@since`
@@ -135,7 +135,7 @@ and why, is in
135
135
 
136
136
  ## Status
137
137
 
138
- Beta (`0.7.0`), published on [PyPI](https://pypi.org/project/python-libei/)
138
+ Beta (`0.8.1`), published on [PyPI](https://pypi.org/project/python-libei/)
139
139
  since `0.1.0`, and **the API is not frozen** — expect renames before 1.0.
140
140
 
141
141
  The injection path is exercised end to end against the real libraries by the
@@ -188,17 +188,27 @@ Exactly what was run, when, and against which versions:
188
188
 
189
189
  | Needs | For |
190
190
  | --- | --- |
191
- | 1.1 | `Region.mapping_id`, `Region.convert_point()`, `Device.region_at()` |
191
+ | 1.1 | `Region.mapping_id`, `Device.region_at()` |
192
192
  | 1.4 | ping/pong round trips (`Context.new_ping()`), `Context.disconnect()`, touch cancellation (`Touch.cancel()`) |
193
193
  | 1.5 | `eis.Client.pid` |
194
194
  | 1.6 | `Device.text_utf8()` / `text_keysym()` and TEXT events, `Seat.request_device()`, `Eis.set_flag()` |
195
195
 
196
196
  Nothing is resolved until it is called, so a build without one of these
197
197
  costs you only that call — it raises `LibraryNotFoundError` naming the
198
- missing symbol, while the rest of the package keeps working. The one
199
- exception is `Event.touch_up_event`, which degrades instead of raising:
200
- on libei older than 1.4 it reports `is_cancel=False`, since a library
201
- with no notion of cancellation genuinely never sends one.
198
+ missing symbol, while the rest of the package keeps working. Two
199
+ accessors degrade instead of raising, because every supported version
200
+ exports the symbol and only the answer changed — so there is nothing to
201
+ resolve and nothing to report:
202
+
203
+ - `Event.touch_up_event` reports `is_cancel=False` on libei older than
204
+ 1.4, since a library with no notion of cancellation genuinely never
205
+ sends one.
206
+ - `eis.Event.emulating_sequence` reads 0 on libei older than 1.6
207
+ whatever the client sent: libeis queued the start_emulating event
208
+ without ever copying the sequence into it, until 1.6.0 added the
209
+ missing assignment. A 0 on an older build is indistinguishable from a
210
+ client that really sent 0. The client-side
211
+ `ei.Event.emulating_sequence` is unaffected.
202
212
 
203
213
  These versions were established by building libei 1.2.1 and diffing its
204
214
  exported symbols against every binding here, not by reading `@since`
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-libei"
7
- version = "0.7.0"
7
+ version = "0.8.1"
8
8
  description = "Inject, receive and capture input on Wayland from Python: ctypes bindings for libei, libeis and liboeffis, plus the RemoteDesktop and InputCapture portals"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -31,6 +31,6 @@ the full breakdown, including which features need which libei version.
31
31
  Beta: the API is not frozen.
32
32
  """
33
33
 
34
- __version__ = "0.7.0"
34
+ __version__ = "0.8.1"
35
35
 
36
36
  __all__ = ["__version__"]
@@ -219,7 +219,13 @@ region_get_mapping_id = lib.function( # libei 1.1+
219
219
  "ei_region_get_mapping_id", (c_void_p,), c_char_p
220
220
  )
221
221
  # x and y are in/out parameters, overwritten only when the point is inside.
222
- region_convert_point = lib.function( # libei 1.1+
222
+ # No version marker: this one is in libei 1.0.0's own public header and
223
+ # implemented there, so every libei at or above the declared floor exports
224
+ # it. It carried `# libei 1.1+` alongside its genuine 1.1 neighbours
225
+ # `ei_region_get_mapping_id` and `ei_device_region_at`, and the weekly
226
+ # floor job caught it -- building 1.0.0 from source found the symbol
227
+ # present where the marker promised it would be absent.
228
+ region_convert_point = lib.function(
223
229
  "ei_region_convert_point",
224
230
  (c_void_p, POINTER(c_double), POINTER(c_double)),
225
231
  c_bool,
@@ -372,8 +372,7 @@ class Region(CObject):
372
372
 
373
373
  Returns the point with the region's offset subtracted, or ``None``
374
374
  if it falls outside the region -- which is also how you test
375
- membership without a second :meth:`contains` call. Requires
376
- libei 1.1.
375
+ membership without a second :meth:`contains` call.
377
376
  """
378
377
  # x/y are in-out parameters: libei overwrites them only when the
379
378
  # point is inside, so the return value has to gate reading them.
@@ -1127,7 +1126,10 @@ class Context(CObject):
1127
1126
  pointer = _capi.libei.get_event(self)
1128
1127
  if not pointer:
1129
1128
  break
1130
- event = Event.wrap(pointer)
1129
+ # adopt(), not wrap(): ei_get_event() transfers ownership of
1130
+ # the returned reference to the caller, and the unref in
1131
+ # release() below is the one that balances it.
1132
+ event = Event.adopt(pointer)
1131
1133
  assert event is not None
1132
1134
  # try/finally, not a bare call after yield: breaking out of a
1133
1135
  # `for event in ctx.events:` loop (or an exception propagating
@@ -944,7 +944,18 @@ class Event(CObject):
944
944
 
945
945
  @property
946
946
  def emulating_sequence(self) -> int:
947
- """Sequence number of the start_emulating transaction."""
947
+ """Sequence number of the start_emulating transaction.
948
+
949
+ Reads 0 on libei older than 1.6, whatever the client sent. libeis
950
+ queued the event without ever copying the sequence into it, so the
951
+ getter returned a zeroed struct field; upstream added the missing
952
+ assignment in libei 1.6.0. Every version from this package's 1.0.0
953
+ floor up exports the symbol, so there is nothing to raise and no
954
+ way to tell an old library apart from a client that genuinely sent
955
+ 0 -- treat a 0 here as "unknown" unless you know both ends are on
956
+ 1.6. :attr:`libei.ei.Event.emulating_sequence`, the receiver side
957
+ of the same transaction, is unaffected: libei has always stored it.
958
+ """
948
959
  self._require("emulating_sequence", EventType.DEVICE_START_EMULATING)
949
960
  return _capi.libeis.event_emulating_get_sequence(self)
950
961
 
@@ -1150,7 +1161,10 @@ class Eis(CObject):
1150
1161
  pointer = _capi.libeis.get_event(self)
1151
1162
  if not pointer:
1152
1163
  break
1153
- event = Event.wrap(pointer)
1164
+ # adopt(), not wrap(): eis_get_event() transfers ownership of
1165
+ # the returned reference to the caller, and the unref in
1166
+ # release() below is the one that balances it.
1167
+ event = Event.adopt(pointer)
1154
1168
  assert event is not None
1155
1169
  # See ei.Context.events: try/finally so release() still runs
1156
1170
  # if the caller breaks out of the loop (GeneratorExit at the
@@ -1168,9 +1182,11 @@ class Eis(CObject):
1168
1182
  def set_flag(self, flag: Flag) -> None:
1169
1183
  """Change this context's protocol behavior. Requires libei 1.6.
1170
1184
 
1171
- Must be called before the backend is set up, so in practice
1172
- before :meth:`create_for_fd` / :meth:`create_for_socket` -- which
1173
- also means this is only reachable on a context built by hand.
1185
+ Must be called before the backend is set up, so the supported
1186
+ way to use it is the ``flags`` parameter of
1187
+ :meth:`create_for_fd` / :meth:`create_for_socket`, which apply
1188
+ each flag at exactly that point; calling it directly only works
1189
+ on a context built by hand, before its backend is set up.
1174
1190
  Takes one flag, never a bitmask; call it again for another.
1175
1191
  """
1176
1192
  result = _capi.libeis.set_flag(self, flag)