gtk-stream 0.11.6__py3-none-any.whl → 0.12__py3-none-any.whl

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.
gtk_stream/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.11.6'
16
- __version_tuple__ = version_tuple = (0, 11, 6)
15
+ __version__ = version = '0.12'
16
+ __version_tuple__ = version_tuple = (0, 12)
gtk_stream/application.py CHANGED
@@ -15,6 +15,9 @@
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
 
17
17
  import sys
18
+ import threading
19
+ import signal
20
+
18
21
  from . import Gtk, GLib, Gdk
19
22
  from .common import printEvent
20
23
  from .properties import parse_property, get_prop_type, set_parse_prop
@@ -68,14 +71,31 @@ class GtkStreamApp(Gtk.Application):
68
71
  for cb in callback_queue:
69
72
  GLib.idle_add(cb)
70
73
  self.run_when_idle = GLib.idle_add
74
+
75
+ def on_sigint(a,b):
76
+ self.logger.info("SIGINT received, quitting application")
77
+ self.quit()
78
+ signal.signal(signal.SIGINT, on_sigint)
71
79
  self.connect('startup', on_startup)
80
+
81
+ def on_activate(a):
82
+ a.hold()
83
+ self.connect('activate', on_activate)
84
+
85
+ self.attrs_set = threading.Semaphore()
86
+ self.attrs_set.acquire()
72
87
 
73
- def nameWidget(self, id, w):
88
+ def name_widget(self, id, w):
74
89
  if id is not None:
75
90
  self.namedWidgets[id] = w
76
91
 
92
+ def set_attrs(self, attrs):
93
+ for name, val in attrs.items():
94
+ set_parse_prop(self, self, name, val)
95
+ self.attrs_set.release()
96
+
77
97
  @app_message('file-dialog')
78
- def openFileDialog(self, id, parent):
98
+ def open_file_dialog(self, id, parent):
79
99
  dialog = Gtk.FileDialog()
80
100
  dialog.props.modal = True
81
101
  def on_choose(_, b):
@@ -90,7 +110,7 @@ class GtkStreamApp(Gtk.Application):
90
110
  dialog.open(parent = self.namedWindows[parent], callback = on_choose)
91
111
 
92
112
  @app_message('window', single_store)
93
- def newWindow(self, document, id, **attrs):
113
+ def new_window(self, document, id, **attrs):
94
114
  win = Gtk.Window(application=self)
95
115
  for (attr_name, attr_val) in attrs.items():
96
116
  self.logger.debug("Setting attr '%s' on window", attr_name)
@@ -101,31 +121,31 @@ class GtkStreamApp(Gtk.Application):
101
121
  win.present()
102
122
 
103
123
  @app_message('style', style_store)
104
- def addStyle(self, style):
124
+ def add_style(self, style):
105
125
  provider = Gtk.CssProvider()
106
126
  provider.load_from_data(style)
107
127
  Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
108
128
 
109
129
  @app_message('add-icon-path')
110
- def addIconPath(self, path):
130
+ def add_icon_path(self, path):
111
131
  theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
112
132
  theme.add_search_path(path)
113
133
 
114
134
  @app_message('close-window')
115
- def closeWindow(self, id):
135
+ def close_window(self, id):
116
136
  self.namedWindows[id].close()
117
137
 
118
138
  @app_message('remove')
119
- def removeWidget(self, id):
139
+ def remove_widget(self, id):
120
140
  w = self.namedWidgets[id]
121
141
  w.get_parent().remove(w)
122
142
 
123
143
  @app_message('insert', multiple_store)
124
- def insertWidgets(self, documents, into):
144
+ def insert_widgets(self, documents, into):
125
145
  for doc in documents:
126
- self.insertWidget(doc, into)
146
+ self.insert_widget(doc, into)
127
147
 
128
- def insertWidget(self, document, into):
148
+ def insert_widget(self, document, into):
129
149
  if into in self.namedWidgets:
130
150
  w = self.namedWidgets[into]
131
151
  w.insert_child(document)
@@ -133,7 +153,7 @@ class GtkStreamApp(Gtk.Application):
133
153
  raise Exception(f"Error: unknown widget id '{into}'")
134
154
 
135
155
  @app_message('set-prop')
136
- def setProp(self, id, name, value):
156
+ def set_prop(self, id, name, value):
137
157
  w = self.namedWidgets[id]
138
158
  w.set_property(name, parse_property(get_prop_type(w.__class__, name), value)(self))
139
159
 
@@ -59,7 +59,9 @@ function GTK.receive() {
59
59
  import io
60
60
  import sys
61
61
  import os
62
+ import threading
62
63
  import xml.sax as sax
64
+
63
65
  from .parser import GtkStreamXMLHandler
64
66
  from .application import GtkStreamApp
65
67
  from .common import Logger, LogLevel
@@ -75,13 +77,24 @@ function GTK.receive() {
75
77
  logger = Logger(logLevel)
76
78
 
77
79
  app = GtkStreamApp(logger)
78
- handler = GtkStreamXMLHandler(logger,app)
79
- errHandler = GtkStreamErrorHandler()
80
- parser = sax.make_parser()
81
- parser.setContentHandler(handler)
82
- parser.setErrorHandler(errHandler)
83
- try:
84
- parser.parse(io.FileIO(0, 'r', closefd=False))
85
- except Exception as e:
86
- logger.error("Done with exception : %s", e)
87
- handler.quit_application()
80
+
81
+ def parser_main():
82
+ handler = GtkStreamXMLHandler(app)
83
+ errHandler = GtkStreamErrorHandler()
84
+ parser = sax.make_parser()
85
+ parser.setContentHandler(handler)
86
+ parser.setErrorHandler(errHandler)
87
+ try:
88
+ parser.parse(io.FileIO(0, 'r', closefd=False))
89
+ except Exception as e:
90
+ logger.error("Done with exception : %s", e)
91
+ handler.quit_application()
92
+
93
+ parser_thread = threading.Thread(target = parser_main, daemon = True)
94
+ parser_thread.start()
95
+
96
+ # When the parser parses the 'application' tag, it sets the
97
+ # application attributes, and releases the semaphore so the
98
+ # application can start
99
+ app.attrs_set.acquire()
100
+ app.run()
@@ -37,7 +37,7 @@ class Document:
37
37
  """Method to render the document to a widet"""
38
38
  raise Exception("Method 'render' not implemented")
39
39
  def set_properties(self, w):
40
- self.app.nameWidget(self.id, w)
40
+ self.app.name_widget(self.id, w)
41
41
  for (p,v) in self.props.items():
42
42
  val = v(self.app)
43
43
  self.app.logger.debug("Setting property '%s' to '%s' in widget %s", p, val, self.__class__)
gtk_stream/parser.py CHANGED
@@ -52,28 +52,29 @@ WIDGET_DOCUMENTS = {
52
52
  }
53
53
 
54
54
  class GtkStreamXMLHandler(sax.ContentHandler):
55
- def __init__(self, logger, app):
56
- self.logger = logger
55
+ def __init__(self, app):
57
56
  self.app = app
57
+ self.logger = app.logger
58
+
58
59
  self.transition_enter = self.transE_conn
59
60
  self.transition_leave = self.transL_final
60
61
  self.transition_chars = self.ignore_chars
61
- self.namedWidgets = { }
62
- self.windows = { }
62
+
63
+ # Get all messages directly from the application
64
+ # class. This allows defining new messages without
65
+ # touching the parser
66
+ self.messages = {
67
+ f.__tag_name__: self.startMessage(functools.partial(f,self.app), f.__store__)
68
+ for f in self.app.__class__.__dict__.values()
69
+ if hasattr(f, '__tag_name__')
70
+ }
63
71
 
64
72
  def quit_application(self):
65
73
  def cb():
66
74
  self.logger.info("Quitting app")
67
75
  self.app.quit()
68
76
  GLib.idle_add(cb)
69
- self.logger.info("Waiting for app to terminate")
70
- self.app_thread.join()
71
- self.logger.info("App terminated")
72
- sys.exit(0)
73
77
 
74
- def setNamed(self, attrs, ):
75
- if 'id' in attrs:
76
- self.namedWidgets[attrs['id']] = widget
77
78
  def ignore_chars(self, s):
78
79
  pass
79
80
 
@@ -95,32 +96,7 @@ class GtkStreamXMLHandler(sax.ContentHandler):
95
96
  def transE_conn(self, name, attrs):
96
97
  match name:
97
98
  case 'application':
98
- for name, val in attrs.items():
99
- set_parse_prop(self.app, self.app, name, val)
100
-
101
- def on_activate(a):
102
- a.hold()
103
- self.app.connect('activate', on_activate)
104
- def appMain():
105
- self.app.run([])
106
- self.app_thread = threading.Thread(target = appMain)
107
- self.app_thread.start()
108
-
109
- def on_sigint(a,b):
110
- self.logger.info("SIGINT received")
111
- self.quit_application()
112
- signal.signal(signal.SIGINT, on_sigint)
113
-
114
- # Get all messages directly from the application
115
- # class. This allows defining new messages without
116
- # touching the parser
117
- self.messages = {
118
- f.__tag_name__: self.startMessage(functools.partial(f,self.app), f.__store__)
119
- for f in self.app.__class__.__dict__.values()
120
- if hasattr(f, '__tag_name__')
121
- }
122
- self.logger.debug("Messages: %s", self.messages)
123
-
99
+ self.app.set_attrs(attrs)
124
100
  self.transition_enter = self.transE_message
125
101
  self.transition_leave = self.transL_tag('application', self.transE_final, self.transL_final)
126
102
  case _:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gtk-stream
3
- Version: 0.11.6
3
+ Version: 0.12
4
4
  Summary: A simple stream-oriented GUI protocol
5
5
  Author-email: Marc Coiffier <marc.coiffier@univ-grenoble-alpes.fr>
6
6
  Project-URL: Homepage, https://coiffier.net/projects/gtk-stream/
@@ -1,14 +1,14 @@
1
1
  gtk_stream/__init__.py,sha256=y6JLknVFexWrSo_Zl7-TXrPR6EQ5XVMeFO1bUzLN9Lg,98
2
- gtk_stream/_version.py,sha256=RuR7_99HIJZnbMWO9BLw2NHLj3e0QsUnhmSY4oBBd3U,413
3
- gtk_stream/application.py,sha256=Au4MngStEIKQdGnl-H6eGWDt923onqRDjW1mPFB9M8I,4911
4
- gtk_stream/command_line.py,sha256=Gq90sMePDmQfz6EByMEzmyGzxTLsmLv930s10WGAHaQ,2854
2
+ gtk_stream/_version.py,sha256=eOKjFr4-OgtTmAgooUIWvbplNekszFVZVHe7TLPOdeU,408
3
+ gtk_stream/application.py,sha256=SrWn_lHJNCyswOB9rPV3Mn5TcnDlAZXHZ5x6A6E5SdQ,5488
4
+ gtk_stream/command_line.py,sha256=g7Sed0ydnDGKyWHT09murwR-3vZyIKXRWgM4Oi0qDE4,3278
5
5
  gtk_stream/common.py,sha256=xdscxYgBg_Ux6iyk26gB-AMSgoUIqlZUPgso5YS_gKE,2106
6
- gtk_stream/parser.py,sha256=juAXyp-YP2Ju7zhhjY6filTAE84v2Ry3gBKOztCeHlw,6664
6
+ gtk_stream/parser.py,sha256=75SYm-5O5Q4TLxq3BfWhuMrxC3-gNLHR4J2gOh0YJg8,5628
7
7
  gtk_stream/properties.py,sha256=RjdRgKUSldIK4Nsij8leBANJicf6oP-Nr53tYI4uEE8,3551
8
8
  gtk_stream/documents/__init__.py,sha256=T9mIonSi9DWrpXQzbjq0s0TPU0hB7HylfhMA20OfWIg,831
9
9
  gtk_stream/documents/classes/Box.py,sha256=d01o2-JQ3-k0VjvvY8E7mly-u_f1v1NqYz1IDjHZLUo,1381
10
10
  gtk_stream/documents/classes/Button.py,sha256=21bVI7DUWmiusboxdsimTgcqKtLqzQydhS9ifIt4R64,1512
11
- gtk_stream/documents/classes/Document.py,sha256=eZ-nT62UfO_ZUsxOR89hFLiBzpxMuNlbcjdZ4yJIzZo,2356
11
+ gtk_stream/documents/classes/Document.py,sha256=_SHqP0ebCDTag0dmi-LdlhopCImtgy0utVp5G3IqgHM,2357
12
12
  gtk_stream/documents/classes/Dropdown.py,sha256=8fIUX1HCWIjUfKLPy9NYsW6OskhkontoNDTsCZ7qKxw,2446
13
13
  gtk_stream/documents/classes/Entry.py,sha256=KcBwjSu4tI30bQxPlSFSLPxFEUbTaqAdoAzd0XSQciY,1112
14
14
  gtk_stream/documents/classes/FlowBox.py,sha256=UoVYS2j_osOV-IgbVoaqluTBCiaXus5dq2e9qhAu2Xo,1225
@@ -24,8 +24,8 @@ gtk_stream/documents/classes/Separator.py,sha256=uw_EgAKs_6pNA8nrOLzruIlJfk4uaog
24
24
  gtk_stream/documents/classes/Stack.py,sha256=YA6NDzZL2u4Ko8GXtx8Or-jEWGMCEw2cC1HNkAMRw-8,1030
25
25
  gtk_stream/documents/classes/Switch.py,sha256=jQVuxqS9Pmpp1ymB_dbJPxasJNpm4e35ry0JYPHdAsk,1275
26
26
  gtk_stream/documents/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- gtk_stream-0.11.6.dist-info/METADATA,sha256=iRmfaDjvwaay_mEkJ2Qxg7u0EdLVzM8hHL4ldOKRPDI,807
28
- gtk_stream-0.11.6.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
29
- gtk_stream-0.11.6.dist-info/entry_points.txt,sha256=PmhKTb4MMQM6dN2HJcoDSMI8L0lZIFIlFn-BgdfPDpo,60
30
- gtk_stream-0.11.6.dist-info/top_level.txt,sha256=vE9zfHGe9Ke7FSe0wBK2WYJI-BpcQNu6xDC3Cu5O8rQ,11
31
- gtk_stream-0.11.6.dist-info/RECORD,,
27
+ gtk_stream-0.12.dist-info/METADATA,sha256=eUB3jj7wt3haezpyhFmYOTqL9YnzG9389R5Vn5dwmIM,805
28
+ gtk_stream-0.12.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
29
+ gtk_stream-0.12.dist-info/entry_points.txt,sha256=PmhKTb4MMQM6dN2HJcoDSMI8L0lZIFIlFn-BgdfPDpo,60
30
+ gtk_stream-0.12.dist-info/top_level.txt,sha256=vE9zfHGe9Ke7FSe0wBK2WYJI-BpcQNu6xDC3Cu5O8rQ,11
31
+ gtk_stream-0.12.dist-info/RECORD,,