Является ли `Gtk.Window.set_attached_to` действительно правильным способом позиционирования всплывающего окна относительно виджета в Wayland? - PullRequest
0 голосов
/ 11 ноября 2019

set_attached_to представляется правильным способом позиционирования всплывающего окна относительно виджета в Wayland:

Примеры мест, где указание этого отношения полезно дляinstance [...] всплывающее окно завершения, созданное Gtk.Entry [...]

К сожалению, это только приводит к ошибке

Gdk-Message: 12:13: 16.143: Окно 0x1822340 является временным окном без родителя, приложение не сможет разместить его на экране.

Попытка раскомментировать строку popup.set_parent(entry) добавляет только предупреждение:

(try_entry_popup.py:4539): Gtk-WARNING **: 12: 17: 34.185: Невозможно установить родительский элемент для виджета верхнего уровня

, за которым следует та же ошибка.

Вот минимальный пример:

#!/usr/bin/env python
# stripped down from https://gitlab.gnome.org/GNOME/gtk/issues/1541#note_396391

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

entry = Gtk.Entry()
popup = Gtk.Window(type=Gtk.WindowType.POPUP)
#popup.set_parent(entry)
popup.set_attached_to(entry)
popup.show_all()

layout = Gtk.VBox()
layout.pack_start(entry, False, True, 0)

window = Gtk.Window()
window.connect("destroy", Gtk.main_quit)
window.add(layout)
window.show_all()

Gtk.main()

Из источника завершения ввода похоже, что он определенно должен работать. Используете ли вы частные функции? Или чего мне не хватает?

1 Ответ

1 голос
/ 12 ноября 2019

Ну, не совсем: gtk_window_set_attached_to не имеет никакого отношения к позиционированию, это важно для доступности (a11y) и правильного применения их. Если вы хотите расположить всплывающее окно, вы можете следить за тем, как оно выполняется в https://gitlab.gnome.org/GNOME/gtk/blob/075dcc142aa525778268165095de019b736f3efa/gtk/gtkentrycompletion.c#L1597

Вот очень простая реализация:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

def on_button_clicked(widget):
  popup = Gtk.Window(type=Gtk.WindowType.POPUP)
  # optionally you may set an appropriate type hint, but it's not required.
  popup.set_attached_to(entry)
  popup.set_transient_for(window)

  gdk_window = entry.get_window()
  gdk_window_origin = gdk_window.get_origin()
  x = gdk_window_origin[1]
  y = gdk_window_origin[2]
  allocation = entry.get_allocation()
  x += allocation.x
  y += allocation.y + allocation.height

  popup.move(x, y)
  popup.show_all()

button = Gtk.Button()
button.connect('clicked', on_button_clicked)
entry = Gtk.Entry()
layout = Gtk.VBox()
layout.pack_start(button, False, True, 0)
layout.pack_start(entry, False, True, 0)

window = Gtk.Window()
window.connect("destroy", Gtk.main_quit)
window.add(layout)
window.show_all()

Gtk.main()
...