From 5d8f94979e86a1d87d86e757f811fa6ea797d60e Mon Sep 17 00:00:00 2001 From: Jussi Kukkonen Date: Sun, 10 Mar 2013 21:36:53 +0200 Subject: [Gtk] Upgrade to Gtk+3, GStreamer 1.0 and python-gi This includes: * Player (manual) drawing changed to use Cairo * GenericModel now directly inherits from TreeModel * lots of syntax changes Fixes #13. Fixes #14. Signed-off-by: Jussi Kukkonen --- src/dleyna-control.py | 13 ++-- src/msd/msd_browse.py | 6 +- src/msd/msd_generic_model.py | 111 +++++++++++++++++------------- src/msd/msd_main_window.py | 71 ++++++++++---------- src/msd/msd_player.py | 156 ++++++++++++++++++++++--------------------- src/msd/msd_search.py | 6 +- src/msd/msd_utils.py | 8 +-- 7 files changed, 196 insertions(+), 175 deletions(-) diff --git a/src/dleyna-control.py b/src/dleyna-control.py index 5ef0973..9b5c4f0 100755 --- a/src/dleyna-control.py +++ b/src/dleyna-control.py @@ -20,10 +20,10 @@ # Mark Ryan # -import pygtk -pygtk.require('2.0') -import gtk -import glib +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gst', '1.0') +from gi.repository import GObject, Gtk, Gst import dbus import dbus.service import dbus.mainloop.glib @@ -31,7 +31,8 @@ import dbus.mainloop.glib from msd.msd_main_window import * if __name__ == "__main__": - gtk.gdk.threads_init() + GObject.threads_init() + Gst.init(None) try: del os.environ["http_proxy"]; except Exception, e: @@ -39,4 +40,4 @@ if __name__ == "__main__": dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) state = State() main_window = MainWindow(state) - gtk.main() + Gtk.main() diff --git a/src/msd/msd_browse.py b/src/msd/msd_browse.py index 2bb1b56..888b8fa 100644 --- a/src/msd/msd_browse.py +++ b/src/msd/msd_browse.py @@ -19,9 +19,9 @@ # Jussi Kukkonen # -import pygtk -pygtk.require('2.0') -import gtk +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk from msd_generic_model import * from msd_sort_order import * diff --git a/src/msd/msd_generic_model.py b/src/msd/msd_generic_model.py index b13b9d1..eb15933 100644 --- a/src/msd/msd_generic_model.py +++ b/src/msd/msd_generic_model.py @@ -24,9 +24,10 @@ # def _fetch_items(self, start, count) # which needs to make sure _on_reply() or _on_error() is called. -import pygtk -pygtk.require('2.0') -import gtk +import sys +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import GLib, GObject, Gtk import dateutil.parser from msd_upnp import * @@ -90,7 +91,7 @@ class _ResultArray(dict): return dict.__len__(self) -class GenericModel(gtk.GenericTreeModel): +class GenericModel(GObject.GObject, Gtk.TreeModel): # columns COL_DISPLAY_NAME = 0 COL_ARTIST = 1 @@ -203,18 +204,20 @@ class GenericModel(gtk.GenericTreeModel): return self.__length_is_known def __on_inserted (self, row): - path = (row,) + path = Gtk.TreePath((row,)) self.row_inserted (path, self.get_iter (path)) def __on_changed (self, row): - path = (row,) + path = Gtk.TreePath((row,)) self.row_changed (path, self.get_iter (path)) def __on_deleted (self, row): - self.row_deleted ((row,)) + self.row_deleted (Gtk.TreePath((row,))) def __init__(self): - gtk.GenericTreeModel.__init__(self) + GObject.GObject.__init__(self) + + self.__stamp = GLib.random_int_range(-2147483648, 2147483647) empty_array = ["Loading...",None, None, None, None, False] self.__items = _ResultArray(empty_array, on_inserted = self.__on_inserted, @@ -257,57 +260,71 @@ class GenericModel(gtk.GenericTreeModel): self.__items.set_length(0 + self.__static_items) self.set_request_range(0, GenericModel.max_items_per_fetch - 1) - def on_get_flags(self): - return gtk.TREE_MODEL_LIST_ONLY + def do_get_flags(self): + return Gtk.TreeModelFlags.LIST_ONLY - def on_get_n_columns(self): + def do_get_n_columns(self): return len(self.column_types) - def on_get_column_type(self, n): + def do_get_column_type(self, n): return self.column_types[n] - def on_get_iter(self, path): - # return internal row reference (key) for use in on_* methods - retval = None + def do_get_iter(self, path): + # return iterator for use in other do_* methods. + # user_data is the index of the refered row. if len(self.__items) > 0 and path[0] < len(self.__items): - retval = path[0] - return retval + tree_iter = Gtk.TreeIter() + tree_iter.stamp = self.__stamp + tree_iter.user_data = path[0] + return (True, tree_iter) + else: + return (False, None) - def on_get_path(self, rowref): - return (rowref, ) + def do_get_path(self, tree_iter): + if tree_iter.user_data is None: + return Gtk.TreePath((None,)) + return Gtk.TreePath((tree_iter.user_data,)) - def on_get_value(self, rowref, col): + def do_get_value(self, tree_iter, col): try: - return self.__items[rowref][col] + if (col == self.COL_LOADED): + return bool(self.__items[tree_iter.user_data][col]) + elif self.__items[tree_iter.user_data][col] == None: + return "" + else: + return self.__items[tree_iter.user_data][col].encode('utf-8') except KeyError: return None - def on_iter_next(self, rowref): - retval = None - if rowref + 1 < len(self.__items): - retval = rowref + 1 - return retval - - def on_iter_children(self, rowref): - retval = 0 - if rowref: - retval = None - return retval + def do_iter_next(self, tree_iter): + length = len(self.__items) + if tree_iter.user_data is None and length > 0: + # return iter to first row + tree_iter.user_data = 0 + return (True, tree_iter) + elif tree_iter.user_data < length - 1: + # return iter to next row + tree_iter.user_data += 1 + return (True, tree_iter) + else: + return (False, None) - def on_iter_has_child(self, rowref): + def do_iter_has_child(self, tree_iter): return False - def on_iter_n_children(self, rowref): - retval = 0 - if not rowref: - retval = len(self.__items) - return retval - - def on_iter_nth_child(self, rowref, child): - retval = None - if not rowref and child < len(self.__items): - retval = child - return retval - - def on_iter_parent(self, child): - return None + def do_iter_n_children(self, parent_iter): + if parent_iter is None: + # special case: return number of top level children + return len(self.__items) + return 0 + + def do_iter_nth_child(self, parent_iter, n): + if parent_iter != None or n >= len(self.__items): + return (False, None) + tree_iter = Gtk.TreeIter() + tree_iter.stamp = self.__stamp + tree_iter.user_data = n + return (True, tree_iter) + + def do_iter_parent(self, child_iter): + return (False, None) diff --git a/src/msd/msd_main_window.py b/src/msd/msd_main_window.py index 7801672..265d0b3 100644 --- a/src/msd/msd_main_window.py +++ b/src/msd/msd_main_window.py @@ -18,10 +18,9 @@ # Mark Ryan # -import pygtk -pygtk.require('2.0') -import gtk -import glib +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gdk, GdkPixbuf, Gtk import dbus import dbus.service import dbus.mainloop.glib @@ -43,17 +42,17 @@ class MainWindow(object): def destroy(self, widget, data=None): if self.__overlay: self.__overlay.cancel_playback() - gtk.main_quit() + Gtk.main_quit() def __append_server_list_row(self, list_store, key, value): name, image = value if image: image = image.get_pixbuf() - image = image.scale_simple(32, 32, gtk.gdk.INTERP_BILINEAR) + image = image.scale_simple(32, 32, GdkPixbuf.InterpType.BILINEAR) return list_store.append([image, name, key]) def __create_server_list_store(self): - list_store = gtk.ListStore(gtk.gdk.Pixbuf, str, str) + list_store = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str) for key, value in self.__state.get_server_list().iteritems(): self.__append_server_list_row(list_store, key, value) return list_store @@ -92,16 +91,16 @@ class MainWindow(object): def __create_server_list(self, table): liststore = self.__create_server_list_store() - treeview = gtk.TreeView(liststore) + treeview = Gtk.TreeView(liststore) treeview.set_headers_visible(True) - column = gtk.TreeViewColumn() + column = Gtk.TreeViewColumn() column.set_title("Servers") - renderer = gtk.CellRendererPixbuf() - column.pack_start(renderer, expand=False) + renderer = Gtk.CellRendererPixbuf() + column.pack_start(renderer, False) column.add_attribute(renderer, 'pixbuf', 0) - renderer = gtk.CellRendererText() - column.pack_start(renderer, expand=False) + renderer = Gtk.CellRendererText() + column.pack_start(renderer, False) column.add_attribute(renderer, 'text', 1) treeview.append_column(column) @@ -109,8 +108,8 @@ class MainWindow(object): treeview.get_selection().connect("changed", self.__server_selected) - scrollwin = gtk.ScrolledWindow() - scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC); + scrollwin = Gtk.ScrolledWindow() + scrollwin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); scrollwin.add(treeview) table.attach(scrollwin, left_attach=0, right_attach=1, top_attach=0, bottom_attach=1) @@ -126,7 +125,7 @@ class MainWindow(object): model.flush() tv.set_model(model) - def __cell_data_func(self, column, cell, model, tree_iter): + def __cell_data_func(self, column, cell, model, tree_iter, userdata): path = model.get_path (tree_iter) requested_range = model.get_request_range() @@ -152,9 +151,9 @@ class MainWindow(object): model.set_request_range(max(0, start), end) def __create_column(self, treeview, name, col, width, sort_by, cell_data_func=None): - renderer = gtk.CellRendererText() - column = gtk.TreeViewColumn(name, renderer) - column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + renderer = Gtk.CellRendererText() + column = Gtk.TreeViewColumn(name, renderer) + column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_fixed_width(width) column.add_attribute(renderer, 'text', col) column.connect("clicked", self.__column_clicked, sort_by) @@ -202,7 +201,7 @@ class MainWindow(object): self.__window.add(self.__overlay.get_container()) def __create_common_list(self, store): - treeview = gtk.TreeView(store) + treeview = Gtk.TreeView(store) treeview.set_headers_visible(True) treeview.set_fixed_height_mode(True) @@ -214,20 +213,20 @@ class MainWindow(object): treeview.set_headers_clickable(True) treeview.set_rules_hint(True) - scrollwin = gtk.ScrolledWindow() - scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC); + scrollwin = Gtk.ScrolledWindow() + scrollwin.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); scrollwin.add(treeview) return (scrollwin, treeview) def __create_browse_view(self, notebook): - tree_store = gtk.TreeStore(str, str, str, str) + tree_store = Gtk.TreeStore(str, str, str, str) scrollwin, treeview = self.__create_common_list(tree_store) treeview.connect("row-activated", self.__content_clicked) self.__browse_view = treeview; - notebook.append_page(scrollwin, gtk.Label("Browse")) + notebook.append_page(scrollwin, Gtk.Label(label="Browse")) def __create_search_list(self, container): - list_store = gtk.ListStore(str, str, str, str) + list_store = Gtk.ListStore(str, str, str, str) scrollwin, treeview = self.__create_common_list(list_store) container.pack_start(scrollwin, True, True, 0) treeview.connect("row-activated", self.__content_clicked) @@ -238,15 +237,15 @@ class MainWindow(object): self.__server_selected(self.__server_view.get_selection()) def __create_check_box(self, title, container): - cb = gtk.CheckButton(title) + cb = Gtk.CheckButton(title) cb.set_active(True) cb.connect("toggled", self.__search_criteria_changed) container.pack_start(cb, True, True, MainWindow.container_padding) return cb def __create_search_controls(self, container): - label = gtk.Label("Search: ") - self.__search_entry = gtk.Entry() + label = Gtk.Label(label="Search: ") + self.__search_entry = Gtk.Entry() self.__search_entry.set_text("") self.__search_entry.connect("activate", self.__search_criteria_changed) container.pack_start(label, True, True, MainWindow.container_padding) @@ -257,12 +256,13 @@ class MainWindow(object): self.__videos = self.__create_check_box("Video", container) def __create_search_view(self, notebook): - vbox = gtk.VBox(False, 0) - hbox = gtk.HBox(True, 0) + vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, + homogeneous=True) self.__create_search_list(vbox) self.__create_search_controls(hbox) vbox.pack_start(hbox, False, True, MainWindow.container_padding) - notebook.append_page(vbox, gtk.Label("Search")) + notebook.append_page(vbox, Gtk.Label(label="Search")) def __page_changed(self, notebook, page, page_number): sel = self.__server_view.get_selection() @@ -270,7 +270,7 @@ class MainWindow(object): self.__change_server(page_number, sel) def __create_notebook(self, table): - notebook = gtk.Notebook() + notebook = Gtk.Notebook() self.__create_search_view(notebook) self.__create_browse_view(notebook) notebook.connect("switch-page", self.__page_changed) @@ -279,14 +279,14 @@ class MainWindow(object): self.__notebook = notebook def __create_widgets(self, window): - table = gtk.Table(rows=1, columns=4, homogeneous=True) + table = Gtk.Table(rows=1, columns=4, homogeneous=True) self.__create_server_list(table) self.__create_notebook(table) window.add(table) self.__main_view = table def __create_window(self): - window = gtk.Window(gtk.WINDOW_TOPLEVEL) + window = Gtk.Window(Gtk.WindowType.TOPLEVEL) window.set_title("Media Service Demo") window.set_resizable(True) window.set_default_size(640, 480) @@ -319,6 +319,7 @@ class MainWindow(object): self.__server_view.set_cursor(liststore.get_path(rowref)) def __init__(self, state): + self.__sort_order = SortOrder() self.__search_path = None self.__browse_path = None self.__state = state @@ -326,8 +327,6 @@ class MainWindow(object): self.__state.set_found_server_cb(self.__found_server) self.__create_window() self.__overlay = None - self.__sort_order = SortOrder() - liststore = self.__server_view.get_model() rowref = liststore.get_iter_first() if rowref: diff --git a/src/msd/msd_player.py b/src/msd/msd_player.py index 1a3a9e7..5d1ca97 100644 --- a/src/msd/msd_player.py +++ b/src/msd/msd_player.py @@ -18,13 +18,18 @@ # Mark Ryan # -import pygtk -pygtk.require('2.0') -import glib -import gtk -import pygst -pygst.require("0.10") -import gst +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +gi.require_version('Gst', '1.0') +from gi.repository import GLib, Gtk, Gst, Gdk, GdkPixbuf + +# For window.get_xid() +from gi.repository import GdkX11 + +# For xvimagesink.set_window_handle() +from gi.repository import GstVideo + import datetime from msd_utils import * @@ -36,10 +41,11 @@ class PlayWindowBase(object): self.__url = url self.__close_window = close_window - self.__container = gtk.VBox(False, 0) - self.drawing_area = gtk.DrawingArea() - self.private_area = gtk.VBox(True, 0) - self.ok_button = gtk.Button("Close") + self.__container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + self.drawing_area = Gtk.DrawingArea() + self.private_area = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, + homogeneous=True) + self.ok_button = Gtk.Button("Close") self.ok_button.connect("clicked", self.quit) self.__container.pack_start(self.drawing_area, True, True, 0) self.__container.pack_start(self.private_area, False, False, 0) @@ -54,10 +60,9 @@ class PlayWindowBase(object): def cancel_playback(self): pass - def draw_image(self, image): + def draw_image(self, image, context): x = 0 y = 0 - gc = self.drawing_area.get_style().fg_gc[gtk.STATE_NORMAL] rect = self.drawing_area.get_allocation() width_scale = image.get_width() / float(rect.width) height_scale = image.get_height() / float(rect.height) @@ -78,9 +83,9 @@ class PlayWindowBase(object): scaled_image = image.scale_simple(int(image.get_width() / divisor), int(image.get_height() / divisor), - gtk.gdk.INTERP_BILINEAR) - self.drawing_area.window.draw_pixbuf(gc, scaled_image, 0, 0, x, - y, -1, -1) + GdkPixbuf.InterpType.BILINEAR) + Gdk.cairo_set_source_pixbuf (context, scaled_image, x, y) + context.paint() class PlayWindowImage(PlayWindowBase): @@ -90,14 +95,15 @@ class PlayWindowImage(PlayWindowBase): try: image = image_from_file(url) self.__image = image.get_pixbuf() - self.drawing_area.connect("expose-event", self.__draw) + self.drawing_area.connect("draw", self.__draw) except Exception: pass self.get_container().show_all() - def __draw(self, area, event): - self.draw_image(self.__image) + def __draw(self, widget, context): + if self.__image: + self.draw_image(self.__image, context) return True class GStreamerWindow(PlayWindowBase): @@ -105,28 +111,28 @@ class GStreamerWindow(PlayWindowBase): def __init__(self, name, url, close_window): PlayWindowBase.__init__(self, name, url, close_window) - self.player = gst.element_factory_make("playbin2", "player") + self.player = Gst.ElementFactory.make("playbin", "player") gsbus = self.player.get_bus() gsbus.add_signal_watch() gsbus.connect("message", self.gs_message_cb) self.player.set_property("uri", url) - button_bar = gtk.HBox(False, 6) - - align = gtk.Alignment(0.5, 0.5, 0.0, 0.0) + button_bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, + spacing=6) + align = Gtk.Alignment.new(0.5, 1.0, 0.0, 0.0) button_bar.pack_start(align, False, False, 0) - self.__play_pause_button = gtk.Button() + self.__play_pause_button = Gtk.Button() self.__play_pause_button.connect("clicked", self.__play_pause) - self.__play_pause_image = gtk.Image() - self.__play_pause_image.set_from_stock(gtk.STOCK_MEDIA_PAUSE, - gtk.ICON_SIZE_BUTTON) + self.__play_pause_image = Gtk.Image() + self.__play_pause_image.set_from_stock(Gtk.STOCK_MEDIA_PAUSE, + Gtk.IconSize.BUTTON) self.__play_pause_button.add(self.__play_pause_image) align.add(self.__play_pause_button) - self.__scale = gtk.HScale() - self.__adjustment = gtk.Adjustment(0, 0, 0, + self.__scale = Gtk.HScale() + self.__adjustment = Gtk.Adjustment(0, 0, 0, 1.0, 30.0, 1.0) self.__adjustment.connect("value-changed", self.__adjusted) self.__scale.set_adjustment(self.__adjustment) @@ -137,38 +143,35 @@ class GStreamerWindow(PlayWindowBase): self.get_container().show_all() self.__update_pos_id = 0 - self.__state = gst.STATE_NULL - self.player.set_state(gst.STATE_PLAYING) + self.__state = Gst.State.NULL + self.player.set_state(Gst.State.PLAYING) def __play_pause(self, button): - if (self.__state == gst.STATE_PLAYING): - self.player.set_state(gst.STATE_PAUSED) + if (self.__state == Gst.State.PLAYING): + self.player.set_state(Gst.State.PAUSED) else: - self.player.set_state(gst.STATE_PLAYING) + self.player.set_state(Gst.State.PLAYING) def __update_pos(self, user_data=None): - try: - pos = self.player.query_position(gst.FORMAT_TIME, None)[0] - if pos != -1: - pos = pos / 1000000000.0 - self.__adjustment.handler_block_by_func(self.__adjusted) - self.__adjustment.set_value(pos) - self.__adjustment.handler_unblock_by_func(self.__adjusted) - except Exception: - pass + success, pos = self.player.query_position(Gst.Format.TIME) + if success: + pos = pos / 1000000000.0 + self.__adjustment.handler_block_by_func(self.__adjusted) + self.__adjustment.set_value(pos) + self.__adjustment.handler_unblock_by_func(self.__adjusted) return True def cancel_playback(self): - self.player.set_state(gst.STATE_NULL) + self.player.set_state(Gst.State.NULL) def quit(self, button): - self.player.set_state(gst.STATE_NULL) + self.player.set_state(Gst.State.NULL) PlayWindowBase.quit(self, button) def __seek (self, position): - self.player.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, - gst.SEEK_TYPE_SET, position, - gst.SEEK_TYPE_NONE, -1.0) + self.player.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH, + Gst.SeekType.SET, position, + Gst.SeekType.NONE, -1.0) def __adjusted(self, adjustment): self.__seek(adjustment.get_value() * 1000000000.0) @@ -182,37 +185,34 @@ class GStreamerWindow(PlayWindowBase): return self.__state = state - if (self.__state > gst.STATE_NULL and + if (self.__state > Gst.State.NULL and self.__adjustment.get_upper() == 0.0): - try: - duration = self.player.query_duration(gst.FORMAT_TIME, None) - if duration[0] != -1: - self.__adjustment.set_upper(duration[0] / 1000000000) - except Exception: - pass - - if self.__state == gst.STATE_PLAYING: - self.__play_pause_image.set_from_stock(gtk.STOCK_MEDIA_PAUSE, - gtk.ICON_SIZE_BUTTON) + success, duration = self.player.query_duration(Gst.Format.TIME) + if success: + self.__adjustment.set_upper(duration / 1000000000) + + if self.__state == Gst.State.PLAYING: + self.__play_pause_image.set_from_stock(Gtk.STOCK_MEDIA_PAUSE, + Gtk.IconSize.BUTTON) if self.__update_pos_id == 0: - self.__update_pos_id = glib.timeout_add(500, + self.__update_pos_id = GLib.timeout_add(500, self.__update_pos, None) else: - self.__play_pause_image.set_from_stock(gtk.STOCK_MEDIA_PLAY, - gtk.ICON_SIZE_BUTTON) + self.__play_pause_image.set_from_stock(Gtk.STOCK_MEDIA_PLAY, + Gtk.IconSize.BUTTON) if self.__update_pos_id != 0: - glib.source_remove(self.__update_pos_id) + GLib.source_remove(self.__update_pos_id) self.__update_pos_id = 0 def gs_message_cb(self, bus, message): - if message.type == gst.MESSAGE_EOS or message.type == gst.MESSAGE_ERROR: + if message.type == Gst.MessageType.EOS or message.type == Gst.MessageType.ERROR: self.__seek(0) - self.player.set_state(gst.STATE_PAUSED) - elif message.type == gst.MESSAGE_STATE_CHANGED: + self.player.set_state(Gst.State.PAUSED) + elif message.type == Gst.MessageType.STATE_CHANGED: (old, state, pending) = message.parse_state_changed() self.__update_ui (state) - elif message.type == gst.MESSAGE_ASYNC_DONE: + elif message.type == Gst.MessageType.ASYNC_DONE: self.__update_pos() class PlayWindowAudio(GStreamerWindow): @@ -224,28 +224,32 @@ class PlayWindowAudio(GStreamerWindow): try: image = image_from_file(album_art_url) self.__image = image.get_pixbuf() - self.drawing_area.connect("expose-event", self.__draw) + self.drawing_area.connect("draw", self.__draw) except Exception: pass - def __draw(self, area, event): - self.draw_image(self.__image) + def __draw(self, widget, context): + if self.__image: + self.draw_image(self.__image, context) return True class PlayWindowVideo(GStreamerWindow): + def __on_realize(self, widget): + self.__xid = self.drawing_area.get_property('window').get_xid() + def __init__(self, name, url, close_window): GStreamerWindow.__init__(self, name, url, close_window) + # get window XID when widget is realized + self.__xid = None + self.drawing_area.connect ("realize", self.__on_realize) + gsbus = self.player.get_bus() gsbus.enable_sync_message_emission() gsbus.connect("sync-message::element", self.gs_sync_message_cb) - def gs_sync_message_cb(self, bus, message): - if message.structure != None and (message.structure.get_name() == - "prepare-xwindow-id"): + if message.get_structure().get_name() == "prepare-window-handle": message.src.set_property("force-aspect-ratio", True) - gtk.gdk.threads_enter() - message.src.set_xwindow_id(self.drawing_area.window.xid) - gtk.gdk.threads_leave() + message.src.set_window_handle(self.__xid) diff --git a/src/msd/msd_search.py b/src/msd/msd_search.py index 82356c6..22a766d 100644 --- a/src/msd/msd_search.py +++ b/src/msd/msd_search.py @@ -19,9 +19,9 @@ # Jussi Kukkonen # -import pygtk -pygtk.require('2.0') -import gtk +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk import cStringIO from msd_generic_model import * diff --git a/src/msd/msd_utils.py b/src/msd/msd_utils.py index e55d17d..35fd266 100644 --- a/src/msd/msd_utils.py +++ b/src/msd/msd_utils.py @@ -19,9 +19,9 @@ # import tempfile -import pygtk -pygtk.require('2.0') -import gtk +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk import urllib2 import os @@ -33,7 +33,7 @@ def image_from_file(url): with tmpfile: message = urllib2.urlopen(url, None, 15) tmpfile.write(message.read()) - image = gtk.Image() + image = Gtk.Image() image.set_from_file(tmpfile.name) finally: os.unlink(tmpFileName) -- cgit v1.2.1