@@ -174,6 +174,10 @@ def _take_selection(element: xa11y.Element) -> str:
174174 return ""
175175
176176
177+ def _take_selection_matches (element : xa11y .Element | None , * , selection : str ) -> bool :
178+ return element is not None and _take_selection (element ) == selection
179+
180+
177181def _take_combo_index (elements : list [xa11y .Element ]) -> int :
178182 """Return the one-based index of the visible Takes combo box."""
179183 visible = [
@@ -219,21 +223,96 @@ def _activate_take_option(option: xa11y.Locator, selection: str) -> None:
219223
220224 # Selecting a UIA row or pressing an AX static text does not consistently
221225 # commit a Qt combo choice. A pointer click emits the activation event.
222- xa11y .input_sim ().click (option_element )
226+ pointer_target = option_element
227+ if (
228+ sys .platform == "darwin"
229+ and option_element .role == "static_text"
230+ and option_row is not None
231+ and option_row .role in {"list_item" , "menu_item" , "table_row" }
232+ ):
233+ pointer_target = option_row
234+ xa11y .input_sim ().click (pointer_target )
235+
236+
237+ def _open_take_combo (combo : xa11y .Locator ) -> None :
238+ combo_actions = set (combo .element ().actions )
239+ if "show_menu" in combo_actions :
240+ combo .show_menu ()
241+ elif "expand" in combo_actions :
242+ combo .expand ()
243+ else :
244+ combo .press ()
223245
224246
225- def _wait_for_take_selection (combo : xa11y .Locator , selection : str ) -> None :
226- """Confirm a highlighted Qt combo row when activation did not commit it."""
247+ def _take_option (combo : xa11y .Locator , selection : str ) -> xa11y .Locator :
248+ option_selector = (
249+ f"list_item[name='{ selection } '], "
250+ f"table_row[name='{ selection } '], "
251+ f"static_text[name='{ selection } ']"
252+ )
253+ option = combo .descendant (option_selector ).first ()
254+ try :
255+ option .wait_visible (timeout = 3.0 )
256+ except xa11y .TimeoutError :
257+ pid = combo .element ().pid
258+ if pid is None :
259+ raise AssertionError ("Take combo does not expose its application PID" ) from None
260+ option = xa11y .App .by_pid (pid ).locator (option_selector ).first ()
261+ option .wait_visible (timeout = 10.0 )
262+ return option
263+
264+
265+ def _press_take_option (option : xa11y .Locator ) -> bool :
266+ """Activate an option through AX when pointer input did not commit it."""
267+ option_element = option .element ()
268+ if "press" in option_element .actions :
269+ option .press ()
270+ return True
271+
272+ option_row = option_element .parent ()
273+ if option_row is not None and "press" in option_row .actions :
274+ option_row .press ()
275+ return True
276+ return False
227277
228- def is_selected (element ):
229- return element is not None and _take_selection (element ) == selection
278+
279+ def _wait_for_take_selection (
280+ combo : xa11y .Locator ,
281+ option : xa11y .Locator ,
282+ selection : str ,
283+ ) -> None :
284+ """Confirm a highlighted Qt combo row when activation did not commit it."""
230285
231286 try :
232- combo .wait_until (is_selected , timeout = 1.0 )
287+ combo .wait_until (
288+ partial (_take_selection_matches , selection = selection ),
289+ timeout = 1.0 ,
290+ )
233291 return
234292 except xa11y .TimeoutError :
235- xa11y .input_sim ().press ("Enter" )
236- combo .wait_until (is_selected , timeout = 10.0 )
293+ pass
294+
295+ if sys .platform == "darwin" :
296+ try :
297+ option .wait_visible (timeout = 0.5 )
298+ except xa11y .TimeoutError :
299+ _open_take_combo (combo )
300+ option = _take_option (combo , selection )
301+ if _press_take_option (option ):
302+ try :
303+ combo .wait_until (
304+ partial (_take_selection_matches , selection = selection ),
305+ timeout = 3.0 ,
306+ )
307+ return
308+ except xa11y .TimeoutError :
309+ pass
310+
311+ xa11y .input_sim ().press ("Enter" )
312+ combo .wait_until (
313+ partial (_take_selection_matches , selection = selection ),
314+ timeout = 10.0 ,
315+ )
237316
238317
239318def _job_specific_text_field (dialog : xa11y .Locator , nth : int ) -> xa11y .Locator :
@@ -343,31 +422,12 @@ def select_takes(dialog: xa11y.Locator, selection: str) -> None:
343422 if current == selection :
344423 return
345424
346- combo_actions = set (combo .element ().actions )
347- if "show_menu" in combo_actions :
348- combo .show_menu ()
349- elif "expand" in combo_actions :
350- combo .expand ()
351- else :
352- combo .press ()
425+ _open_take_combo (combo )
353426
354- option_selector = (
355- f"list_item[name='{ selection } '], "
356- f"table_row[name='{ selection } '], "
357- f"static_text[name='{ selection } ']"
358- )
359- option = combo .descendant (option_selector ).first ()
360- try :
361- option .wait_visible (timeout = 3.0 )
362- except xa11y .TimeoutError :
363- pid = combo .element ().pid
364- if pid is None :
365- raise AssertionError ("Take combo does not expose its application PID" ) from None
366- option = xa11y .App .by_pid (pid ).locator (option_selector ).first ()
367- option .wait_visible (timeout = 10.0 )
427+ option = _take_option (combo , selection )
368428
369429 _activate_take_option (option , selection )
370- _wait_for_take_selection (combo , selection )
430+ _wait_for_take_selection (combo , option , selection )
371431
372432
373433def set_tile_rendering (
0 commit comments