Daniel Brötzmann pushed to branch master at gajim / gajim
Commits:
-
3ee48358
by wurstsalat at 2021-12-19T13:30:51+01:00
-
deae7b07
by wurstsalat at 2021-12-19T13:30:51+01:00
-
2a0de98c
by wurstsalat at 2021-12-19T13:30:51+01:00
3 changed files:
Changes:
| ... | ... | @@ -12,21 +12,27 @@ |
| 12 | 12 |
# You should have received a copy of the GNU General Public License
|
| 13 | 13 |
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
| 14 | 14 |
|
| 15 |
-from typing import Optional # pylint: disable=unused-import
|
|
| 15 |
+from __future__ import annotations
|
|
| 16 |
+from typing import Any
|
|
| 17 |
+from typing import List
|
|
| 18 |
+from typing import Optional
|
|
| 16 | 19 |
|
| 17 | 20 |
import logging
|
| 18 | 21 |
import time
|
| 19 | 22 |
|
| 20 | 23 |
from gi.repository import GObject
|
| 24 |
+from gi.repository import Gdk
|
|
| 21 | 25 |
from gi.repository import Gtk
|
| 22 | 26 |
|
| 23 | 27 |
from nbxmpp.namespaces import Namespace
|
| 24 | 28 |
|
| 25 | 29 |
from gajim.common import app
|
| 30 |
+from gajim.common import types
|
|
| 26 | 31 |
from gajim.common.const import JingleState
|
| 27 | 32 |
from gajim.common.const import KindConstant
|
| 28 | 33 |
from gajim.common.helpers import AdditionalDataDict
|
| 29 | 34 |
from gajim.common.i18n import _
|
| 35 |
+from gajim.common.jingle_rtp import JingleAudio
|
|
| 30 | 36 |
from gajim.common.nec import NetworkEvent
|
| 31 | 37 |
|
| 32 | 38 |
from .gstreamer import create_gtk_widget
|
| ... | ... | @@ -50,7 +56,7 @@ class CallWidget(Gtk.Box): |
| 50 | 56 |
),
|
| 51 | 57 |
}
|
| 52 | 58 |
|
| 53 |
- def __init__(self, account, contact):
|
|
| 59 |
+ def __init__(self, account: str, contact: types.BareContact) -> None:
|
|
| 54 | 60 |
Gtk.Box.__init__(self)
|
| 55 | 61 |
self.set_no_show_all(True)
|
| 56 | 62 |
|
| ... | ... | @@ -62,7 +68,7 @@ def __init__(self, account, contact): |
| 62 | 68 |
# having to show a new call row
|
| 63 | 69 |
self._incoming_video_event = None
|
| 64 | 70 |
|
| 65 |
- self._jingle = {
|
|
| 71 |
+ self._jingle: dict(str, JingleObject) = {
|
|
| 66 | 72 |
'audio': JingleObject(
|
| 67 | 73 |
JingleState.NULL,
|
| 68 | 74 |
self._update_audio),
|
| ... | ... | @@ -77,20 +83,22 @@ def __init__(self, account, contact): |
| 77 | 83 |
self.add(self._ui.av_box)
|
| 78 | 84 |
self.connect('destroy', self._on_destroy)
|
| 79 | 85 |
|
| 80 |
- dtmf = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#']
|
|
| 86 |
+ dtmf: list(str) = [
|
|
| 87 |
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#']
|
|
| 81 | 88 |
for key in dtmf:
|
| 82 | 89 |
button = self._ui.get_object(key + '_button')
|
| 83 |
- button.connect('pressed', self._on_num_button_pressed, key)
|
|
| 84 |
- button.connect('released', self._on_num_button_released)
|
|
| 90 |
+ button.connect(
|
|
| 91 |
+ 'button-press-event', self._on_num_button_press, key)
|
|
| 92 |
+ button.connect('button-release-event', self._on_num_button_release)
|
|
| 85 | 93 |
|
| 86 | 94 |
self._ui.connect_signals(self)
|
| 87 | 95 |
|
| 88 |
- def _on_destroy(self, *args):
|
|
| 96 |
+ def _on_destroy(self, *args: Any) -> None:
|
|
| 89 | 97 |
for jingle_type in ('audio', 'video'):
|
| 90 | 98 |
self._close_jingle_content(jingle_type, shutdown=True)
|
| 91 | 99 |
self._jingle.clear()
|
| 92 | 100 |
|
| 93 |
- def detect_av(self):
|
|
| 101 |
+ def detect_av(self) -> None:
|
|
| 94 | 102 |
if (self._contact.supports(Namespace.JINGLE_ICE_UDP) and
|
| 95 | 103 |
app.is_installed('FARSTREAM')):
|
| 96 | 104 |
self._jingle['audio'].available = self._contact.supports(
|
| ... | ... | @@ -104,23 +112,23 @@ def detect_av(self): |
| 104 | 112 |
self._jingle['audio'].available = False
|
| 105 | 113 |
self._jingle['video'].available = False
|
| 106 | 114 |
|
| 107 |
- def get_jingle_available(self, content_type):
|
|
| 115 |
+ def get_jingle_available(self, content_type: str) -> bool:
|
|
| 108 | 116 |
return self._jingle[content_type].available
|
| 109 | 117 |
|
| 110 |
- def _on_call_with_mic(self, _button):
|
|
| 118 |
+ def _on_call_with_mic(self, _button: Gtk.Button) -> None:
|
|
| 111 | 119 |
self._on_jingle_button_toggled(['audio'])
|
| 112 | 120 |
self._ui.av_start_box.hide()
|
| 113 | 121 |
|
| 114 |
- def _on_call_with_mic_and_cam(self, _button):
|
|
| 122 |
+ def _on_call_with_mic_and_cam(self, _button: Gtk.Button) -> None:
|
|
| 115 | 123 |
self._on_jingle_button_toggled(['audio', 'video'])
|
| 116 | 124 |
self._ui.av_start_box.hide()
|
| 117 | 125 |
|
| 118 |
- def _on_answer_video_clicked(self, button):
|
|
| 126 |
+ def _on_answer_video_clicked(self, button: Gtk.Button) -> None:
|
|
| 119 | 127 |
self.accept_call(self._incoming_video_event)
|
| 120 | 128 |
self._incoming_video_event = None
|
| 121 | 129 |
button.hide()
|
| 122 | 130 |
|
| 123 |
- def _on_end_call_clicked(self, _widget):
|
|
| 131 |
+ def _on_end_call_clicked(self, _button: Gtk.Button) -> None:
|
|
| 124 | 132 |
self._close_jingle_content('audio')
|
| 125 | 133 |
self._close_jingle_content('video')
|
| 126 | 134 |
self._ui.jingle_audio_state.set_no_show_all(True)
|
| ... | ... | @@ -129,10 +137,10 @@ def _on_end_call_clicked(self, _widget): |
| 129 | 137 |
self.hide()
|
| 130 | 138 |
self.emit('call-ended')
|
| 131 | 139 |
|
| 132 |
- def _on_video(self, *args):
|
|
| 140 |
+ def _on_video(self, _button: Gtk.Button) -> None:
|
|
| 133 | 141 |
self._on_jingle_button_toggled(['video'])
|
| 134 | 142 |
|
| 135 |
- def _on_jingle_button_toggled(self, jingle_types):
|
|
| 143 |
+ def _on_jingle_button_toggled(self, jingle_types: List[str]) -> None:
|
|
| 136 | 144 |
if all(item in jingle_types for item in ['audio', 'video']):
|
| 137 | 145 |
# Both 'audio' and 'video' in jingle_types
|
| 138 | 146 |
sid = self._client.get_module('Jingle').start_audio_video(
|
| ... | ... | @@ -160,7 +168,7 @@ def _on_jingle_button_toggled(self, jingle_types): |
| 160 | 168 |
self._set_jingle_state('video', JingleState.CONNECTING, sid)
|
| 161 | 169 |
self._store_outgoing_call(sid)
|
| 162 | 170 |
|
| 163 |
- def _store_outgoing_call(self, sid):
|
|
| 171 |
+ def _store_outgoing_call(self, sid: str) -> None:
|
|
| 164 | 172 |
additional_data = AdditionalDataDict()
|
| 165 | 173 |
additional_data.set_value('gajim', 'sid', sid)
|
| 166 | 174 |
app.storage.archive.insert_into_logs(
|
| ... | ... | @@ -170,17 +178,30 @@ def _store_outgoing_call(self, sid): |
| 170 | 178 |
KindConstant.CALL_OUTGOING,
|
| 171 | 179 |
additional_data=additional_data)
|
| 172 | 180 |
|
| 173 |
- def _on_num_button_pressed(self, _widget, num):
|
|
| 181 |
+ def _on_num_button_press(self,
|
|
| 182 |
+ _button: Gtk.Button,
|
|
| 183 |
+ _event: Gdk.EventButton,
|
|
| 184 |
+ num: int
|
|
| 185 |
+ ) -> None:
|
|
| 174 | 186 |
self._get_audio_content().start_dtmf(num)
|
| 175 | 187 |
|
| 176 |
- def _on_num_button_released(self, _released):
|
|
| 188 |
+ def _on_num_button_release(self,
|
|
| 189 |
+ _button: Gtk.Button,
|
|
| 190 |
+ _event: Gdk.EventButton
|
|
| 191 |
+ ) -> None:
|
|
| 177 | 192 |
self._get_audio_content().stop_dtmf()
|
| 178 | 193 |
|
| 179 |
- def _on_mic_volume_changed(self, _widget, value):
|
|
| 194 |
+ def _on_mic_volume_changed(self,
|
|
| 195 |
+ _button: Gtk.VolumeButton,
|
|
| 196 |
+ value: float
|
|
| 197 |
+ ) -> None:
|
|
| 180 | 198 |
self._get_audio_content().set_mic_volume(value / 100)
|
| 181 | 199 |
app.settings.set('audio_input_volume', int(value))
|
| 182 | 200 |
|
| 183 |
- def _on_output_volume_changed(self, _widget, value):
|
|
| 201 |
+ def _on_output_volume_changed(self,
|
|
| 202 |
+ _button: Gtk.VolumeButton,
|
|
| 203 |
+ value: float
|
|
| 204 |
+ ) -> None:
|
|
| 184 | 205 |
self._get_audio_content().set_out_volume(value / 100)
|
| 185 | 206 |
app.settings.set('audio_output_volume', int(value))
|
| 186 | 207 |
|
| ... | ... | @@ -195,7 +216,7 @@ def process_event(self, event): |
| 195 | 216 |
self._on_jingle_error(event)
|
| 196 | 217 |
|
| 197 | 218 |
def _on_jingle_request(self, event):
|
| 198 |
- content_types = []
|
|
| 219 |
+ content_types: list(str) = []
|
|
| 199 | 220 |
for item in event.contents:
|
| 200 | 221 |
content_types.append(item.media)
|
| 201 | 222 |
if not any(item in ('audio', 'video') for item in content_types):
|
| ... | ... | @@ -273,7 +294,7 @@ def _on_jingle_error(self, event): |
| 273 | 294 |
JingleState.ERROR,
|
| 274 | 295 |
reason=event.reason)
|
| 275 | 296 |
|
| 276 |
- def start_call(self):
|
|
| 297 |
+ def start_call(self) -> None:
|
|
| 277 | 298 |
audio_state = self._jingle['audio'].state
|
| 278 | 299 |
video_state = self._jingle['video'].state
|
| 279 | 300 |
if audio_state == JingleState.NULL and video_state == JingleState.NULL:
|
| ... | ... | @@ -307,7 +328,8 @@ def accept_call(self, session): |
| 307 | 328 |
if video is not None:
|
| 308 | 329 |
session.approve_content('video')
|
| 309 | 330 |
|
| 310 |
- def decline_call(self, session):
|
|
| 331 |
+ @staticmethod
|
|
| 332 |
+ def decline_call(session):
|
|
| 311 | 333 |
if not session:
|
| 312 | 334 |
return
|
| 313 | 335 |
|
| ... | ... | @@ -322,7 +344,7 @@ def decline_call(self, session): |
| 322 | 344 |
if video is not None:
|
| 323 | 345 |
session.reject_content('video')
|
| 324 | 346 |
|
| 325 |
- def _update_audio(self):
|
|
| 347 |
+ def _update_audio(self) -> None:
|
|
| 326 | 348 |
audio_state = self._jingle['audio'].state
|
| 327 | 349 |
video_state = self._jingle['video'].state
|
| 328 | 350 |
if self._jingle['video'].available:
|
| ... | ... | @@ -381,7 +403,7 @@ def _update_audio(self): |
| 381 | 403 |
if not self._jingle['audio'].sid:
|
| 382 | 404 |
self._ui.audio_buttons_box.set_sensitive(False)
|
| 383 | 405 |
|
| 384 |
- def _update_video(self):
|
|
| 406 |
+ def _update_video(self) -> None:
|
|
| 385 | 407 |
audio_state = self._jingle['audio'].state
|
| 386 | 408 |
video_state = self._jingle['video'].state
|
| 387 | 409 |
|
| ... | ... | @@ -494,7 +516,10 @@ def _set_jingle_state(self, jingle_type: str, state: str, sid: str = None, |
| 494 | 516 |
jingle.sid = new_sid
|
| 495 | 517 |
jingle.update()
|
| 496 | 518 |
|
| 497 |
- def _stop_jingle(self, sid=None, reason=None):
|
|
| 519 |
+ def _stop_jingle(self,
|
|
| 520 |
+ sid: Optional[str] = None,
|
|
| 521 |
+ reason: Optional[str] = None
|
|
| 522 |
+ ) -> None:
|
|
| 498 | 523 |
audio_sid = self._jingle['audio'].sid
|
| 499 | 524 |
video_sid = self._jingle['video'].sid
|
| 500 | 525 |
if audio_sid and sid in (audio_sid, None):
|
| ... | ... | @@ -502,8 +527,10 @@ def _stop_jingle(self, sid=None, reason=None): |
| 502 | 527 |
if video_sid and sid in (video_sid, None):
|
| 503 | 528 |
self._close_jingle_content('video')
|
| 504 | 529 |
|
| 505 |
- def _close_jingle_content(self, jingle_type: str,
|
|
| 506 |
- shutdown: Optional[bool] = False) -> None:
|
|
| 530 |
+ def _close_jingle_content(self,
|
|
| 531 |
+ jingle_type: str,
|
|
| 532 |
+ shutdown: Optional[bool] = False
|
|
| 533 |
+ ) -> None:
|
|
| 507 | 534 |
jingle = self._jingle[jingle_type]
|
| 508 | 535 |
if not jingle.sid:
|
| 509 | 536 |
return
|
| ... | ... | @@ -520,7 +547,7 @@ def _close_jingle_content(self, jingle_type: str, |
| 520 | 547 |
jingle.state = JingleState.NULL
|
| 521 | 548 |
jingle.update()
|
| 522 | 549 |
|
| 523 |
- def _get_audio_content(self):
|
|
| 550 |
+ def _get_audio_content(self) -> Optional[JingleAudio]:
|
|
| 524 | 551 |
session = self._client.get_module('Jingle').get_jingle_session(
|
| 525 | 552 |
self._contact.jid, self._jingle['audio'].sid)
|
| 526 | 553 |
return session.get_content('audio')
|
| ... | ... | @@ -12,13 +12,19 @@ |
| 12 | 12 |
# You should have received a copy of the GNU General Public License
|
| 13 | 13 |
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
| 14 | 14 |
|
| 15 |
+from typing import Optional
|
|
| 16 |
+from typing import Tuple
|
|
| 17 |
+ |
|
| 18 |
+from gi.repository import Gtk
|
|
| 15 | 19 |
try:
|
| 16 | 20 |
from gi.repository import Gst
|
| 17 | 21 |
except Exception:
|
| 18 | 22 |
pass
|
| 19 | 23 |
|
| 20 | 24 |
|
| 21 |
-def create_gtk_widget():
|
|
| 25 |
+def create_gtk_widget() -> Tuple[Optional[Gst.Element],
|
|
| 26 |
+ Optional[Gtk.Widget],
|
|
| 27 |
+ Optional[str]]:
|
|
| 22 | 28 |
gtkglsink = Gst.ElementFactory.make('gtkglsink', None)
|
| 23 | 29 |
if gtkglsink is not None:
|
| 24 | 30 |
glsinkbin = Gst.ElementFactory.make('glsinkbin', None)
|
| ... | ... | @@ -28,6 +28,7 @@ |
| 28 | 28 |
from importlib import import_module
|
| 29 | 29 |
from functools import wraps
|
| 30 | 30 |
from functools import lru_cache
|
| 31 |
+from pathlib import Path
|
|
| 31 | 32 |
|
| 32 | 33 |
try:
|
| 33 | 34 |
from PIL import Image
|
| ... | ... | @@ -39,7 +40,9 @@ |
| 39 | 40 |
from gi.repository import GLib
|
| 40 | 41 |
from gi.repository import Pango
|
| 41 | 42 |
from gi.repository import GdkPixbuf
|
| 43 |
+import cairo
|
|
| 42 | 44 |
import nbxmpp
|
| 45 |
+from nbxmpp import JID
|
|
| 43 | 46 |
from nbxmpp.structs import LocationData
|
| 44 | 47 |
|
| 45 | 48 |
from gajim.common import app
|
| ... | ... | @@ -155,8 +158,13 @@ def icon_exists(name: str) -> bool: |
| 155 | 158 |
return _icon_theme.has_icon(name)
|
| 156 | 159 |
|
| 157 | 160 |
|
| 158 |
-def load_icon(icon_name, widget=None, size=16, pixbuf=False,
|
|
| 159 |
- scale=None, flags=Gtk.IconLookupFlags.FORCE_SIZE):
|
|
| 161 |
+def load_icon(icon_name: str,
|
|
| 162 |
+ widget: Optional[Any] = None,
|
|
| 163 |
+ size: int = 16,
|
|
| 164 |
+ pixbuf: bool = False,
|
|
| 165 |
+ scale: Optional[int] = None,
|
|
| 166 |
+ flags: Gtk.IconLookupFlags = Gtk.IconLookupFlags.FORCE_SIZE
|
|
| 167 |
+ ) -> Optional[Union[GdkPixbuf.Pixbuf, cairo.Surface]]:
|
|
| 160 | 168 |
|
| 161 | 169 |
if widget is not None:
|
| 162 | 170 |
scale = widget.get_scale_factor()
|
| ... | ... | @@ -170,15 +178,16 @@ def load_icon(icon_name, widget=None, size=16, pixbuf=False, |
| 170 | 178 |
icon_name, size, scale, flags)
|
| 171 | 179 |
if iconinfo is None:
|
| 172 | 180 |
log.info('No icon found for %s', icon_name)
|
| 173 |
- return
|
|
| 181 |
+ return None
|
|
| 174 | 182 |
if pixbuf:
|
| 175 | 183 |
return iconinfo.load_icon()
|
| 176 | 184 |
return iconinfo.load_surface(None)
|
| 177 | 185 |
except GLib.GError as error:
|
| 178 | 186 |
log.error('Unable to load icon %s: %s', icon_name, str(error))
|
| 187 |
+ return None
|
|
| 179 | 188 |
|
| 180 | 189 |
|
| 181 |
-def get_app_icon_list(scale_widget):
|
|
| 190 |
+def get_app_icon_list(scale_widget: Any) -> List[GdkPixbuf.Pixbuf]:
|
|
| 182 | 191 |
pixbufs = []
|
| 183 | 192 |
for size in (16, 32, 48, 64, 128):
|
| 184 | 193 |
pixbuf = load_icon('org.gajim.Gajim', scale_widget, size, pixbuf=True)
|
| ... | ... | @@ -194,15 +203,15 @@ def get_icon_name(name: str, |
| 194 | 203 |
name = 'notinroster'
|
| 195 | 204 |
|
| 196 | 205 |
if iconset is not None:
|
| 197 |
- return '%s-%s' % (iconset, name)
|
|
| 206 |
+ return f'{iconset}-{name}'
|
|
| 198 | 207 |
|
| 199 | 208 |
if transport is not None:
|
| 200 |
- return '%s-%s' % (transport, name)
|
|
| 209 |
+ return f'{transport}-{name}'
|
|
| 201 | 210 |
|
| 202 | 211 |
iconset = app.settings.get('iconset')
|
| 203 | 212 |
if not iconset:
|
| 204 | 213 |
iconset = 'dcraven'
|
| 205 |
- return '%s-%s' % (iconset, name)
|
|
| 214 |
+ return f'{iconset}-{name}'
|
|
| 206 | 215 |
|
| 207 | 216 |
|
| 208 | 217 |
def load_user_iconsets() -> None:
|
| ... | ... | @@ -517,7 +526,7 @@ def format_fingerprint(fingerprint: str) -> str: |
| 517 | 526 |
return buf.rstrip().upper()
|
| 518 | 527 |
|
| 519 | 528 |
|
| 520 |
-def find_widget(name, container):
|
|
| 529 |
+def find_widget(name: str, container: Gtk.Widget) -> Optional[Gtk.Widget]:
|
|
| 521 | 530 |
for child in container.get_children():
|
| 522 | 531 |
if Gtk.Buildable.get_name(child) == name:
|
| 523 | 532 |
return child
|
| ... | ... | @@ -527,7 +536,7 @@ def find_widget(name, container): |
| 527 | 536 |
|
| 528 | 537 |
|
| 529 | 538 |
class MultiLineLabel(Gtk.Label):
|
| 530 |
- def __init__(self, *args, **kwargs):
|
|
| 539 |
+ def __init__(self, *args: Any, **kwargs: any) -> None:
|
|
| 531 | 540 |
Gtk.Label.__init__(self, *args, **kwargs)
|
| 532 | 541 |
self.set_line_wrap(True)
|
| 533 | 542 |
self.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
|
| ... | ... | @@ -535,16 +544,16 @@ def __init__(self, *args, **kwargs): |
| 535 | 544 |
|
| 536 | 545 |
|
| 537 | 546 |
class MaxWidthComboBoxText(Gtk.ComboBoxText):
|
| 538 |
- def __init__(self, *args, **kwargs):
|
|
| 547 |
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
| 539 | 548 |
Gtk.ComboBoxText.__init__(self, *args, **kwargs)
|
| 540 |
- self._max_width = 100
|
|
| 549 |
+ self._max_width: int = 100
|
|
| 541 | 550 |
text_renderer = self.get_cells()[0]
|
| 542 | 551 |
text_renderer.set_property('ellipsize', Pango.EllipsizeMode.END)
|
| 543 | 552 |
|
| 544 |
- def set_max_size(self, size):
|
|
| 553 |
+ def set_max_size(self, size: int) -> None:
|
|
| 545 | 554 |
self._max_width = size
|
| 546 | 555 |
|
| 547 |
- def do_get_preferred_width(self):
|
|
| 556 |
+ def do_get_preferred_width(self) -> Tuple[int, int]:
|
|
| 548 | 557 |
minimum_width, natural_width = Gtk.ComboBoxText.do_get_preferred_width(
|
| 549 | 558 |
self)
|
| 550 | 559 |
|
| ... | ... | @@ -639,12 +648,16 @@ def scale_pixbuf(pixbuf: GdkPixbuf.Pixbuf, |
| 639 | 648 |
GdkPixbuf.InterpType.BILINEAR)
|
| 640 | 649 |
|
| 641 | 650 |
|
| 642 |
-def scale_pixbuf_from_data(data: bytes, size: int) -> Optional[GdkPixbuf.Pixbuf]:
|
|
| 651 |
+def scale_pixbuf_from_data(data: bytes,
|
|
| 652 |
+ size: int
|
|
| 653 |
+ ) -> Optional[GdkPixbuf.Pixbuf]:
|
|
| 643 | 654 |
pixbuf = get_pixbuf_from_data(data)
|
| 644 | 655 |
return scale_pixbuf(pixbuf, size)
|
| 645 | 656 |
|
| 646 | 657 |
|
| 647 |
-def load_pixbuf(path, size=None):
|
|
| 658 |
+def load_pixbuf(path: Union[str, Path],
|
|
| 659 |
+ size: Optional[int] = None
|
|
| 660 |
+ ) -> Optional[GdkPixbuf.Pixbuf]:
|
|
| 648 | 661 |
try:
|
| 649 | 662 |
if size is None:
|
| 650 | 663 |
return GdkPixbuf.Pixbuf.new_from_file(str(path))
|
| ... | ... | @@ -720,7 +733,10 @@ def get_app_windows(account: str) -> List[Gtk.Window]: |
| 720 | 733 |
return windows
|
| 721 | 734 |
|
| 722 | 735 |
|
| 723 |
-def get_app_window(name, account=None, jid=None):
|
|
| 736 |
+def get_app_window(name: str,
|
|
| 737 |
+ account: Optional[str] = None,
|
|
| 738 |
+ jid: Optional[Union[str, JID]] = None
|
|
| 739 |
+ ) -> Optional[Gtk.Window]:
|
|
| 724 | 740 |
for win in app.app.get_windows():
|
| 725 | 741 |
if type(win).__name__ != name:
|
| 726 | 742 |
continue
|
| ... | ... | @@ -736,7 +752,7 @@ def get_app_window(name, account=None, jid=None): |
| 736 | 752 |
return None
|
| 737 | 753 |
|
| 738 | 754 |
|
| 739 |
-def open_window(name, **kwargs):
|
|
| 755 |
+def open_window(name: str, **kwargs: Any) -> Gtk.Window:
|
|
| 740 | 756 |
window = get_app_window(name,
|
| 741 | 757 |
kwargs.get('account'),
|
| 742 | 758 |
kwargs.get('jid'))
|