[packages/mirage] - rel 3 - added python3 port patches from fedora

baggins baggins at pld-linux.org
Tue Sep 19 14:10:45 CEST 2023


commit 2880527d4403c22963889c5ea5ff2628e3aa350c
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Tue Sep 19 13:18:10 2023 +0200

    - rel 3
    - added python3 port patches from fedora

 glib241-init-workaround.patch          |   13 +
 mirage.spec                            |   42 +-
 pep632-distutils-port.patch            |   11 +
 prevmouse-not-defined-with-click.patch |   16 +
 py3-gtk3.patch                         | 3365 ++++++++++++++++++++++++++++++++
 5 files changed, 3429 insertions(+), 18 deletions(-)
---
diff --git a/mirage.spec b/mirage.spec
index b9d83ea..9af711b 100644
--- a/mirage.spec
+++ b/mirage.spec
@@ -1,26 +1,30 @@
 # TODO
-# - what python-pygtk it realy needs
 # - cleanup and ready to go!
 # - desktop integration (file association)
 Summary:	Fast and simple image viewer in GTK+
 Summary(pl.UTF-8):	Szybka i prosta przeglądarka obrazków w GTK+
 Name:		mirage
 Version:	0.9.5.2
-Release:	2
+Release:	3
 License:	GPL v3+
 Group:		X11/Applications/Graphics
 Source0:	http://download.berlios.de/mirageiv/%{name}-%{version}.tar.bz2
 # Source0-md5:	92191a4496b0a50486ed7299baf6729f
+Patch0:		prevmouse-not-defined-with-click.patch
+Patch1:		glib241-init-workaround.patch
+Patch2:		py3-gtk3.patch
+Patch3:		pep632-distutils-port.patch
 URL:		http://mirageiv.berlios.de/
-BuildRequires:	gtk+2-devel >= 2:2.6.0
-BuildRequires:	python-devel >= 1:2.5
-BuildRequires:	python-gnome-devel
-BuildRequires:	python-pygtk-devel >= 2.6.0
+BuildRequires:	gtk+3-devel
+BuildRequires:	python3-devel
+BuildRequires:	python3-setuptools
 BuildRequires:	rpm-pythonprov
 BuildRequires:	rpmbuild(macros) >= 1.219
 BuildRequires:	sed >= 4.0
+Requires:	gtk3
+Requires:	python3-gobject
+Requires:	python3-cairo
 Requires:	desktop-file-utils
-Requires:	python-gnome
 BuildRoot:	%{tmpdir}/%{name}-%{version}-root-%(id -u -n)
 
 %description
@@ -56,26 +60,27 @@ Cechy:
 
 %prep
 %setup -q
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+
 # Don't remove rebuilt files!
 %{__sed} -i -e '/Cleanup/,$d' setup.py
 
 %build
-%{__python} setup.py build
+%py3_build
 
 %install
 rm -rf $RPM_BUILD_ROOT
-%{__python} setup.py install \
-	--root=$RPM_BUILD_ROOT \
-	--skip-build \
-	--optimize=2
+%py3_install
 
 %{__rm} $RPM_BUILD_ROOT%{_datadir}/%{name}/{CHANGELOG,COPYING,README,TODO,TRANSLATORS}
 
 # ukranian, seems not supported
-rm -r $RPM_BUILD_ROOT%{_datadir}/locale/ua
+%{__rm} -r $RPM_BUILD_ROOT%{_datadir}/locale/ua
 
 %find_lang %{name}
-%py_postclean
 
 %clean
 rm -rf $RPM_BUILD_ROOT
@@ -87,10 +92,11 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(644,root,root,755)
 %doc CHANGELOG README TODO TRANSLATORS
 %attr(755,root,root) %{_bindir}/mirage
-%{py_sitedir}/mirage.py[co]
-%attr(755,root,root) %{py_sitedir}/imgfuncs.so
-%attr(755,root,root) %{py_sitedir}/xmouse.so
-%{py_sitedir}/*.egg-info
+%{py3_sitedir}/__pycache__/*.py*
+%{py3_sitedir}/mirage.py
+%attr(755,root,root) %{py3_sitedir}/imgfuncs.*.so
+%attr(755,root,root) %{py3_sitedir}/xmouse.*.so
+%{py3_sitedir}/*.egg-info
 %{_desktopdir}/mirage.desktop
 %dir %{_datadir}/mirage
 %{_datadir}/mirage/*.png
diff --git a/glib241-init-workaround.patch b/glib241-init-workaround.patch
new file mode 100644
index 0000000..3f67ea3
--- /dev/null
+++ b/glib241-init-workaround.patch
@@ -0,0 +1,13 @@
+--- mirage-0.9.5.2/mirage.py.glib241	2014-08-12 17:55:57.000000000 +0900
++++ mirage-0.9.5.2/mirage.py	2014-08-12 17:52:18.000000000 +0900
+@@ -71,7 +71,9 @@
+ 
+ 	def __init__(self):
+ 		
+-		gtk.gdk.threads_init()
++		import glib
++		if glib.glib_version < (2, 41, 0):
++			gtk.gdk.threads_init()
+ 		
+ 		# FIX THIS! Does not work on windows and what happens if mo-files exists
+ 		# in both dirs?
diff --git a/pep632-distutils-port.patch b/pep632-distutils-port.patch
new file mode 100644
index 0000000..b217ed5
--- /dev/null
+++ b/pep632-distutils-port.patch
@@ -0,0 +1,11 @@
+--- mirage-0.9.5.2/setup.py.distutils	2020-09-10 00:15:48.360874985 +0900
++++ mirage-0.9.5.2/setup.py	2023-01-04 17:40:33.164918841 +0900
+@@ -5,7 +5,7 @@
+ 
+ import os
+ 
+-from distutils.core import setup, Extension
++from setuptools import setup, Extension
+ 
+ def removeall(path):
+ 	if not os.path.isdir(path):
diff --git a/prevmouse-not-defined-with-click.patch b/prevmouse-not-defined-with-click.patch
new file mode 100644
index 0000000..22b3488
--- /dev/null
+++ b/prevmouse-not-defined-with-click.patch
@@ -0,0 +1,16 @@
+--- mirage-0.9.3/mirage.py.debug	2008-03-27 13:05:28.000000000 +0900
++++ mirage-0.9.3/mirage.py	2010-01-29 18:19:24.000000000 +0900
+@@ -2946,10 +2946,11 @@
+ 	def button_pressed(self, widget, event):
+ 		if self.image_loaded:
+ 			# Changes the cursor to the 'resize' cursor, like GIMP, on a middle click:
+-			if (event.button == 2 or event.button == 1) and (self.hscroll.get_property('visible')==True or self.vscroll.get_property('visible')==True):
+-				self.change_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
++			if (event.button == 2 or event.button == 1) :
+ 				self.prevmousex = event.x_root
+ 				self.prevmousey = event.y_root
++				if (self.hscroll.get_property('visible')==True or self.vscroll.get_property('visible')==True) :
++					self.change_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
+ 			# Right-click popup:
+ 			elif self.image_loaded and event.button == 3:
+ 				self.UIManager.get_widget('/Popup').popup(None, None, None, event.button, event.time)
diff --git a/py3-gtk3.patch b/py3-gtk3.patch
new file mode 100644
index 0000000..36baa76
--- /dev/null
+++ b/py3-gtk3.patch
@@ -0,0 +1,3365 @@
+diff -urp '--exclude=build' '--exclude=__pycache__' '--exclude=*~' '--exclude=*.py3' '--exclude=mo' mirage-0.9.5.2.py2/imgfuncs.c mirage-0.9.5.2.py3/imgfuncs.c
+--- mirage-0.9.5.2.py2/imgfuncs.c	2006-05-08 03:06:03.000000000 +0900
++++ mirage-0.9.5.2.py3/imgfuncs.c	2020-09-10 00:15:48.358874990 +0900
+@@ -24,7 +24,7 @@ PyObject *rotate_right(PyObject *self, P
+ 	PyObject *ret;
+ 	
+ 	/* Get Python Arguments */
+-	if(!PyArg_ParseTuple(args, "z#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
++	if(!PyArg_ParseTuple(args, "y#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
+ 	{
+ 		return NULL;
+ 	}
+@@ -51,7 +51,7 @@ PyObject *rotate_right(PyObject *self, P
+ 		}
+ 	}
+ 	
+-	ret = Py_BuildValue("z#iii", a2, length, w2, h2, rws2);
++	ret = Py_BuildValue("y#iii", a2, length, w2, h2, rws2);
+ 	free(a2);
+ 	
+ 	return ret;
+@@ -71,7 +71,7 @@ PyObject *rotate_left(PyObject *self, Py
+ 	PyObject *ret;
+ 	
+ 	/* Get Python Arguments */
+-	if(!PyArg_ParseTuple(args, "z#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
++	if(!PyArg_ParseTuple(args, "y#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
+ 	{
+ 		return NULL;
+ 	}
+@@ -98,7 +98,7 @@ PyObject *rotate_left(PyObject *self, Py
+ 		}
+ 	}
+ 	
+-	ret = Py_BuildValue("z#iii", a2, length, w2, h2, rws2);
++	ret = Py_BuildValue("y#iii", a2, length, w2, h2, rws2);
+ 	free(a2);
+ 	
+ 	return ret;
+@@ -118,7 +118,7 @@ PyObject *rotate_mirror(PyObject *self,
+ 	PyObject *ret;
+ 	
+ 	/* Get Python Arguments */
+-	if(!PyArg_ParseTuple(args, "z#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
++	if(!PyArg_ParseTuple(args, "y#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
+ 	{
+ 		return NULL;
+ 	}
+@@ -141,7 +141,7 @@ PyObject *rotate_mirror(PyObject *self,
+ 		}
+ 	}
+ 	
+-	ret = Py_BuildValue("z#iii", a2, length, w2, h2, rws2);
++	ret = Py_BuildValue("y#iii", a2, length, w2, h2, rws2);
+ 	free(a2);
+ 	
+ 	return ret;
+@@ -161,7 +161,7 @@ PyObject *flip_vert(PyObject *self, PyOb
+ 	PyObject *ret;
+ 	
+ 	/* Get Python Arguments */
+-	if(!PyArg_ParseTuple(args, "z#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
++	if(!PyArg_ParseTuple(args, "y#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
+ 	{
+ 		return NULL;
+ 	}
+@@ -184,7 +184,7 @@ PyObject *flip_vert(PyObject *self, PyOb
+ 		}
+ 	}
+ 	
+-	ret = Py_BuildValue("z#iii", a2, length, w2, h2, rws2);
++	ret = Py_BuildValue("y#iii", a2, length, w2, h2, rws2);
+ 	free(a2);
+ 	
+ 	return ret;
+@@ -204,7 +204,7 @@ PyObject *flip_horiz(PyObject *self, PyO
+ 	PyObject *ret;
+ 	
+ 	/* Get Python Arguments */
+-	if(!PyArg_ParseTuple(args, "z#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
++	if(!PyArg_ParseTuple(args, "y#iiii", &a1, &length, &w1, &h1, &rws1, &psz)) 
+ 	{
+ 		return NULL;
+ 	}
+@@ -227,7 +227,7 @@ PyObject *flip_horiz(PyObject *self, PyO
+ 		}
+ 	}
+ 	
+-	ret = Py_BuildValue("z#iii", a2, length, w2, h2, rws2);
++	ret = Py_BuildValue("y#iii", a2, length, w2, h2, rws2);
+ 	free(a2);
+ 	
+ 	return ret;
+@@ -244,7 +244,17 @@ static PyMethodDef imgfuncs_methods[] =
+ };
+ 
+ /* Module initialization function */
+-void initimgfuncs(void)
++static struct PyModuleDef imgfunc_module =
+ {
+-	Py_InitModule("imgfuncs", imgfuncs_methods);
++    PyModuleDef_HEAD_INIT,
++    "imgfuncs", /* name of module */
++    NULL,          /* module documentation, may be NULL */
++    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
++    imgfuncs_methods
++};
++
++PyMODINIT_FUNC PyInit_imgfuncs(void)
++{
++    return PyModule_Create(&imgfunc_module);
+ }
++
+diff -urp '--exclude=build' '--exclude=__pycache__' '--exclude=*~' '--exclude=*.py3' '--exclude=mo' mirage-0.9.5.2.py2/mirage.py mirage-0.9.5.2.py3/mirage.py
+--- mirage-0.9.5.2.py2/mirage.py	2020-09-10 00:15:11.317964653 +0900
++++ mirage-0.9.5.2.py3/mirage.py	2021-12-01 21:53:00.000000000 +0900
+@@ -23,13 +23,17 @@ You should have received a copy of the G
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ """
+ 
+-import pygtk
+-pygtk.require('2.0')
+-import gtk
+-import os, sys, getopt, ConfigParser, string, gc
++import gi
++gi.require_version("Gtk", "3.0")
++from gi.repository import Gtk as gtk
++from gi.repository import Gdk as gdk
++from gi.repository import GdkPixbuf, GLib
++import os, sys, getopt, configparser, string, gc
+ import random, urllib, gobject, gettext, locale
+ import stat, time, subprocess, shutil, filecmp
+ import tempfile, socket, threading
++import urllib.request
++import functools
+ try:
+ 	import hashlib
+ 	HAS_HASHLIB = True
+@@ -41,25 +45,18 @@ try:
+ 	HAS_IMGFUNCS = True
+ except:
+ 	HAS_IMGFUNCS = False
+-	print "imgfuncs.so module not found, rotating/flipping images will be disabled."
++	print ("imgfuncs.so module not found, rotating/flipping images will be disabled.")
+ try:
+ 	import xmouse
+ 	HAS_XMOUSE = True
+ except:
+ 	HAS_XMOUSE = False
+-	print "xmouse.so module not found, some screenshot capabilities will be disabled."
++	print ("xmouse.so module not found, some screenshot capabilities will be disabled.")
+ try:
+ 	import gconf
+ except:
+ 	pass
+ 
+-if gtk.gtk_version < (2, 10, 0):
+-	sys.stderr.write("Mirage requires GTK+ 2.10.0 or newer..\n")
+-	sys.exit(1)
+-if gtk.pygtk_version < (2, 12, 0):
+-	sys.stderr.write("Mirage requires PyGTK 2.12.0 or newer.\n")
+-	sys.exit(1)
+-	
+ def valid_int(inputstring):
+ 	try:
+ 		x = int(inputstring)
+@@ -71,14 +68,14 @@ class Base:
+ 
+ 	def __init__(self):
+ 		
+-		import glib
+-		if glib.glib_version < (2, 41, 0):
+-			gtk.gdk.threads_init()
++		from gi.repository import GLib
++		if (GLib.MAJOR_VERSION, GLib.MINOR_VERSION, GLib.MICRO_VERSION) < (2, 41, 0):
++			gdk.threads_init()
+ 		
+ 		# FIX THIS! Does not work on windows and what happens if mo-files exists
+ 		# in both dirs?
+-		gettext.install('mirage', '/usr/share/locale', unicode=1)
+-		gettext.install('mirage', '/usr/local/share/locale', unicode=1)
++		gettext.install('mirage', localedir='/usr/share/locale')
++		gettext.install('mirage', localedir='/usr/local/share/locale')
+ 
+ 		# Constants
+ 		self.open_mode_smart = 0
+@@ -131,7 +128,7 @@ class Base:
+ 		self.statusbar_show = True
+ 		self.fullscreen_mode = False
+ 		self.opendialogpath = ""
+-		self.zoom_quality = gtk.gdk.INTERP_BILINEAR
++		self.zoom_quality = GdkPixbuf.InterpType.BILINEAR
+ 		self.recursive = False
+ 		self.verbose = False
+ 		self.image_loaded = False
+@@ -182,6 +179,11 @@ class Base:
+ 		self.recentfiles = ["", "", "", "", ""]
+ 		self.screenshot_delay = 2
+ 		self.thumbpane_bottom_coord_loaded = 0
++		# FIXME
++		# Add this
++		self.load_when_idle = 0
++		self.preload_when_idle = 0
++		self.preload_when_idle2 = 0
+ 
+ 		# Read any passed options/arguments:
+ 		try:
+@@ -217,7 +219,7 @@ class Base:
+ 		# according to XDG specification and as a fallback use ~/.config/mirage
+ 		self.config_dir = (os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config')) + '/mirage'
+ 		# Load config from disk:
+-		conf = ConfigParser.ConfigParser()
++		conf = configparser.ConfigParser(interpolation=None)
+ 		if os.path.isfile(self.config_dir + '/miragerc'):
+ 			conf.read(self.config_dir + '/miragerc')
+ 		if conf.has_option('window', 'w'):
+@@ -237,7 +239,7 @@ class Base:
+ 			bgg = conf.getint('prefs', 'bgcolor-green')
+ 			bgb = conf.getint('prefs', 'bgcolor-blue')
+ 			bgcolor_found = True
+-			self.bgcolor = gtk.gdk.Color(red=bgr, green=bgg, blue=bgb)
++			self.bgcolor = gdk.Color(red=bgr, green=bgg, blue=bgb)
+ 		if conf.has_option('prefs', 'use_last_dir'):
+ 			self.use_last_dir = conf.getboolean('prefs', 'use_last_dir')
+ 		if conf.has_option('prefs', 'last_dir'):
+@@ -261,13 +263,13 @@ class Base:
+ 		if conf.has_option('prefs', 'zoomquality'):
+ 			self.zoomvalue = conf.getint('prefs', 'zoomquality')
+ 			if int(round(self.zoomvalue, 0)) == 0:
+-				self.zoom_quality = gtk.gdk.INTERP_NEAREST
++				self.zoom_quality = GdkPixbuf.InterpType.NEAREST
+ 			elif int(round(self.zoomvalue, 0)) == 1:
+-				self.zoom_quality = gtk.gdk.INTERP_TILES
++				self.zoom_quality = GdkPixbuf.InterpType.TILES
+ 			elif int(round(self.zoomvalue, 0)) == 2:
+-				self.zoom_quality = gtk.gdk.INTERP_BILINEAR
++				self.zoom_quality = GdkPixbuf.InterpType.BILINEAR
+ 			elif int(round(self.zoomvalue, 0)) == 3:
+-				self.zoom_quality = gtk.gdk.INTERP_HYPER
++				self.zoom_quality = GdkPixbuf.InterpType.HYPER
+ 		if conf.has_option('prefs', 'quality_save'):
+ 			self.quality_save = conf.getint('prefs', 'quality_save')
+ 		if conf.has_option('prefs', 'disable_screensaver'):
+@@ -313,29 +315,29 @@ class Base:
+ 
+ 		# Read accel_map file, if it exists
+ 		if os.path.isfile(self.config_dir + '/accel_map'):
+-			gtk.accel_map_load(self.config_dir + '/accel_map')
++			gtk.AccelMap.load(self.config_dir + '/accel_map')
+ 		
+ 		# Directory/ies in which to find application images/pixmaps
+ 		self.resource_path_list = False
+ 		
+-		self.blank_image = gtk.gdk.pixbuf_new_from_file(self.find_path("mirage_blank.png"))
++		self.blank_image = GdkPixbuf.Pixbuf.new_from_file(self.find_path("mirage_blank.png"))
+ 
+ 		# Define the main menubar and toolbar:
+ 		factory = gtk.IconFactory()
+ 		iconname = 'stock_leave-fullscreen.png'
+ 		iconname2 = 'stock_fullscreen.png'
+ 		leave_fullscreen_icon_path = self.find_path(iconname)
+-		pixbuf = gtk.gdk.pixbuf_new_from_file(leave_fullscreen_icon_path)
+-		iconset = gtk.IconSet(pixbuf)
++		pixbuf = GdkPixbuf.Pixbuf.new_from_file(leave_fullscreen_icon_path)
++		iconset = gtk.IconSet.new_from_pixbuf(pixbuf)
+ 		factory.add('leave-fullscreen', iconset)
+ 		factory.add_default()
+ 		fullscreen_icon_path = self.find_path(iconname2)
+-		pixbuf = gtk.gdk.pixbuf_new_from_file(fullscreen_icon_path)
+-		iconset = gtk.IconSet(pixbuf)
++		pixbuf = GdkPixbuf.Pixbuf.new_from_file(fullscreen_icon_path)
++		iconset = gtk.IconSet.new_from_pixbuf(pixbuf)
+ 		factory.add('fullscreen', iconset)
+ 		factory.add_default()
+ 		try:
+-			test = gtk.Button("", gtk.STOCK_LEAVE_FULLSCREEN)
++			test = gtk.Button.new_from_stock(gtk.STOCK_LEAVE_FULLSCREEN)
+ 			leave_fullscreen_icon = gtk.STOCK_LEAVE_FULLSCREEN
+ 			fullscreen_icon = gtk.STOCK_FULLSCREEN
+ 		except:
+@@ -539,16 +541,16 @@ class Base:
+ 			"""
+ 
+ 		# Create interface
+-		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
++		self.window = gtk.Window(type=gtk.WindowType.TOPLEVEL)
+ 		self.update_title()
+ 		icon_path = self.find_path('mirage.png')
+ 		try:
+-			gtk.window_set_default_icon_from_file(icon_path)
++			gtk.Window.set_default_icon_from_file(icon_path)
+ 		except:
+ 			pass
+-		vbox = gtk.VBox(False, 0)
++		vbox = gtk.VBox(homogeneous=False, spacing=0)
+ 		self.UIManager = gtk.UIManager()
+-		actionGroup = gtk.ActionGroup('Actions')
++		actionGroup = gtk.ActionGroup(name='Actions')
+ 		actionGroup.add_actions(actions)
+ 		actionGroup.add_toggle_actions(toggle_actions)
+ 		self.UIManager.insert_action_group(actionGroup, 0)
+@@ -561,71 +563,77 @@ class Base:
+ 		self.toolbar = self.UIManager.get_widget('/MainToolbar')
+ 		vbox.pack_start(self.toolbar, False, False, 0)
+ 		self.layout = gtk.Layout()
+-		self.vscroll = gtk.VScrollbar(None)
++		self.vscroll = gtk.VScrollbar(adjustment=None)
+ 		self.vscroll.set_adjustment(self.layout.get_vadjustment())
+-		self.hscroll = gtk.HScrollbar(None)
++		self.hscroll = gtk.HScrollbar(adjustment=None)
+ 		self.hscroll.set_adjustment(self.layout.get_hadjustment())
+-		self.table = gtk.Table(3, 2, False)
++		self.table = gtk.Table(n_rows = 3, n_columns = 2, homogeneous = False)
+ 
+-		self.thumblist = gtk.ListStore(gtk.gdk.Pixbuf)
+-		self.thumbpane = gtk.TreeView(self.thumblist)
++		self.thumblist = gtk.ListStore(GdkPixbuf.Pixbuf)
++		self.thumbpane = gtk.TreeView(model = self.thumblist)
+ 		self.thumbcolumn = gtk.TreeViewColumn(None)
+ 		self.thumbcell = gtk.CellRendererPixbuf()
+-		self.thumbcolumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
++		self.thumbcolumn.set_sizing(gtk.TreeViewColumnSizing.FIXED)
+ 		self.thumbpane_set_size()
+ 		self.thumbpane.append_column(self.thumbcolumn)
+ 		self.thumbcolumn.pack_start(self.thumbcell, True)
+ 		self.thumbcolumn.set_attributes(self.thumbcell, pixbuf=0)
+-		self.thumbpane.get_selection().set_mode(gtk.SELECTION_SINGLE)
++		self.thumbpane.get_selection().set_mode(gtk.SelectionMode.SINGLE)
+ 		self.thumbpane.set_headers_visible(False)
+ 		self.thumbpane.set_property('can-focus', False)
+ 		self.thumbscroll = gtk.ScrolledWindow()
+-		self.thumbscroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
++		self.thumbscroll.set_policy(gtk.PolicyType.NEVER, gtk.PolicyType.ALWAYS)
+ 		self.thumbscroll.add(self.thumbpane)
+ 		
+-		self.table.attach(self.thumbscroll, 0, 1, 0, 1, 0, gtk.FILL|gtk.EXPAND, 0, 0)
+-		self.table.attach(self.layout, 1, 2, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		self.table.attach(self.hscroll, 1, 2, 1, 2, gtk.FILL|gtk.SHRINK, gtk.FILL|gtk.SHRINK, 0, 0)
+-		self.table.attach(self.vscroll, 2, 3, 0, 1, gtk.FILL|gtk.SHRINK, gtk.FILL|gtk.SHRINK, 0, 0)
++		self.table.attach(self.thumbscroll, 0, 1, 0, 1, 0, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		#
++		self.layout_vbox = gtk.VBox(homogeneous=False, spacing=0)
++		self.layout_vbox.pack_start(self.layout, True, True, 0)
++		self.table.attach(self.layout_vbox, 1, 2, 0, 1, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		#
++		self.table.attach(self.hscroll, 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.SHRINK, gtk.AttachOptions.FILL|gtk.AttachOptions.SHRINK, 0, 0)
++		self.table.attach(self.vscroll, 2, 3, 0, 1, gtk.AttachOptions.FILL|gtk.AttachOptions.SHRINK, gtk.AttachOptions.FILL|gtk.AttachOptions.SHRINK, 0, 0)
+ 		vbox.pack_start(self.table, True, True, 0)
+ 		if not bgcolor_found:
+-			self.bgcolor = gtk.gdk.Color(0, 0, 0) # Default to black
++			self.bgcolor = gdk.Color(0, 0, 0) # Default to black
+ 		if self.simple_bgcolor:
+-			self.layout.modify_bg(gtk.STATE_NORMAL, None)
++			#self.layout.modify_bg(gtk.StateType.NORMAL, None)
++			self.modify_bg(self.layout_vbox, None)
+ 		else:
+-			self.layout.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
++			#self.layout.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++			self.modify_bg(self.layout_vbox, self.bgcolor)
+ 		self.imageview = gtk.Image()
+ 		self.layout.add(self.imageview)
+ 
+ 		self.statusbar = gtk.Statusbar()
+ 		self.statusbar2 = gtk.Statusbar()
+-		self.statusbar.set_has_resize_grip(False)
+-		self.statusbar2.set_has_resize_grip(True)
++		#self.statusbar.set_has_resize_grip(False)
++		#self.statusbar2.set_has_resize_grip(True)
+ 		self.statusbar2.set_size_request(200, -1)
+ 		hbox_statusbar = gtk.HBox()
+-		hbox_statusbar.pack_start(self.statusbar, expand=True)
+-		hbox_statusbar.pack_start(self.statusbar2, expand=False)
++		hbox_statusbar.pack_start(child=self.statusbar, expand=True, fill=True, padding=0)
++		hbox_statusbar.pack_start(child=self.statusbar2, expand=False, fill=True, padding=0)
+ 		vbox.pack_start(hbox_statusbar, False, False, 0)
+ 		self.window.add(vbox)
+-		self.window.set_property('allow-shrink', False)
++		#self.window.set_property('allow-shrink', False)
+ 		self.window.set_default_size(width,height)
+ 		
+ 		# Slideshow control:
+-		self.slideshow_window = gtk.Window(gtk.WINDOW_POPUP)
++		self.slideshow_window = gtk.Window(type=gtk.WindowType.POPUP)
+ 		self.slideshow_controls = gtk.HBox()
+ 		self.ss_back = gtk.Button()
+-		self.ss_back.add(gtk.image_new_from_stock(gtk.STOCK_GO_BACK, gtk.ICON_SIZE_BUTTON))
++		self.ss_back.add(gtk.Image.new_from_stock(gtk.STOCK_GO_BACK, gtk.IconSize.BUTTON))
+ 		self.ss_back.set_property('can-focus', False)
+ 		self.ss_back.connect('clicked', self.goto_prev_image)
+-		self.ss_start = gtk.Button("", gtk.STOCK_MEDIA_PLAY)
++		self.ss_start = gtk.Button.new_from_stock(gtk.STOCK_MEDIA_PLAY)
+ 		self.ss_start.get_child().get_child().get_children()[1].set_text('')
+ 		self.ss_start.set_property('can-focus', False)
+ 		self.ss_start.connect('clicked', self.toggle_slideshow)
+-		self.ss_stop = gtk.Button("", gtk.STOCK_MEDIA_STOP)
++		self.ss_stop = gtk.Button.new_from_stock(gtk.STOCK_MEDIA_STOP)
+ 		self.ss_stop.get_child().get_child().get_children()[1].set_text('')
+ 		self.ss_stop.set_property('can-focus', False)
+ 		self.ss_stop.connect('clicked', self.toggle_slideshow)
+-		self.ss_forward = gtk.Button("", gtk.STOCK_GO_FORWARD)
++		self.ss_forward = gtk.Button.new_from_stock(gtk.STOCK_GO_FORWARD)
+ 		self.ss_forward.get_child().get_child().get_children()[1].set_text('')
+ 		self.ss_forward.set_property('can-focus', False)
+ 		self.ss_forward.connect('clicked', self.goto_next_image)
+@@ -635,33 +643,35 @@ class Base:
+ 		self.slideshow_controls.pack_start(self.ss_forward, False, False, 0)
+ 		self.slideshow_window.add(self.slideshow_controls)
+ 		if self.simple_bgcolor:
+-			self.slideshow_window.modify_bg(gtk.STATE_NORMAL, None)
++			#self.slideshow_window.modify_bg(gtk.StateType.NORMAL, None)
++			self.modify_bg(self.slideshow_window, None)
+ 		else:
+-			self.slideshow_window.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
+-		self.slideshow_window2 = gtk.Window(gtk.WINDOW_POPUP)
++			#self.slideshow_window.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++			self.modify_bg(self.slideshow_window, self.bgcolor)
++		self.slideshow_window2 = gtk.Window(type=gtk.WindowType.POPUP)
+ 		self.slideshow_controls2 = gtk.HBox()
+ 		try:
+-			self.ss_exit = gtk.Button("", gtk.STOCK_LEAVE_FULLSCREEN)
++			self.ss_exit = gtk.Button.new_from_stock(gtk.STOCK_LEAVE_FULLSCREEN)
+ 			self.ss_exit.get_child().get_child().get_children()[1].set_text('')
+ 		except:
+ 			self.ss_exit = gtk.Button()
+-			self.ss_exit.set_image(gtk.image_new_from_stock('leave-fullscreen', gtk.ICON_SIZE_MENU))
++			self.ss_exit.set_image(gtk.image_new_from_stock('leave-fullscreen', gtk.IconSize.MENU))
+ 		self.ss_exit.set_property('can-focus', False)
+ 		self.ss_exit.connect('clicked', self.leave_fullscreen)
+ 		self.ss_randomize = gtk.ToggleButton()
+ 		icon_path = self.find_path('stock_shuffle.png')
+ 		try:
+-			pixbuf = gtk.gdk.pixbuf_new_from_file(icon_path)
+-			iconset = gtk.IconSet(pixbuf)
++			pixbuf = GdkPixbuf.Pixbuf.new_from_file(icon_path)
++			iconset = gtk.IconSet.new_from_pixbuf(pixbuf)
+ 			factory.add('stock-shuffle', iconset)
+ 			factory.add_default()
+-			self.ss_randomize.set_image(gtk.image_new_from_stock('stock-shuffle', gtk.ICON_SIZE_MENU))
++			self.ss_randomize.set_image(gtk.image_new_from_stock('stock-shuffle', gtk.IconSize.MENU))
+ 		except:
+ 			self.ss_randomize.set_label("Rand")
+ 		self.ss_randomize.connect('toggled', self.random_changed)
+ 		
+-		spin_adj = gtk.Adjustment(self.slideshow_delay, 0, 50000, 1,100, 0)
+-		self.ss_delayspin = gtk.SpinButton(spin_adj, 1.0, 0)
++		spin_adj = gtk.Adjustment(value=self.slideshow_delay, lower=0, upper=50000, step_increment=1, page_increment=100, page_size=0)
++		self.ss_delayspin = gtk.SpinButton(adjustment=spin_adj, climb_rate=1.0, digits=0)
+ 		self.ss_delayspin.set_numeric(True)
+ 		self.ss_delayspin.connect('changed', self.delay_changed)
+ 		self.slideshow_controls2.pack_start(self.ss_randomize, False, False, 0)
+@@ -669,9 +679,11 @@ class Base:
+ 		self.slideshow_controls2.pack_start(self.ss_exit, False, False, 0)
+ 		self.slideshow_window2.add(self.slideshow_controls2)
+ 		if self.simple_bgcolor:
+-			self.slideshow_window2.modify_bg(gtk.STATE_NORMAL, None)
++			#self.slideshow_window2.modify_bg(gtk.StateType.NORMAL, None)
++			self.modify_bg(self.slideshow_window2, None)
+ 		else:
+-			self.slideshow_window2.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
++			#self.slideshow_window2.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++			self.modify_bg(self.slideshow_window2, self.bgcolor)
+ 
+ 		# Connect signals
+ 		self.window.connect("delete_event", self.delete_event)
+@@ -679,17 +691,19 @@ class Base:
+ 		self.window.connect("size-allocate", self.window_resized)
+ 		self.window.connect('key-press-event', self.topwindow_keypress)
+ 		self.toolbar.connect('focus', self.toolbar_focused)
+-		self.layout.drag_dest_set(gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, [("text/uri-list", 0, 80)], gtk.gdk.ACTION_DEFAULT)
++		self.layout.drag_dest_set(gtk.DestDefaults.HIGHLIGHT | gtk.DestDefaults.DROP, [gtk.TargetEntry.new("text/uri-list", 0, 80)], gdk.DragAction.DEFAULT)
+ 		self.layout.connect('drag_motion', self.motion_cb)
+ 		self.layout.connect('drag_data_received', self.drop_cb)
+-		self.layout.add_events(gtk.gdk.KEY_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_MOTION_MASK | gtk.gdk.SCROLL_MASK)
++		self.layout.add_events(gdk.EventMask.KEY_PRESS_MASK | gdk.EventMask.POINTER_MOTION_MASK | gdk.EventMask.BUTTON_PRESS_MASK | gdk.EventMask.BUTTON_MOTION_MASK | gdk.EventMask.SCROLL_MASK)
+ 		self.layout.connect("scroll-event", self.mousewheel_scrolled)
+-		self.layout.add_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.KEY_PRESS_MASK)
++		self.layout.add_events(gdk.EventMask.BUTTON_PRESS_MASK | gdk.EventMask.KEY_PRESS_MASK)
+ 		self.layout.connect("button_press_event", self.button_pressed)
+-		self.layout.add_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
++		self.layout.add_events(gdk.EventMask.POINTER_MOTION_MASK | gdk.EventMask.POINTER_MOTION_HINT_MASK | gdk.EventMask.BUTTON_RELEASE_MASK)
+ 		self.layout.connect("motion-notify-event", self.mouse_moved)
+ 		self.layout.connect("button-release-event", self.button_released)
+-		self.imageview.connect("expose-event", self.expose_event)
++		#self.imageview.connect("expose-event", self.expose_event)
++		# FIXME
++		self.imageview.connect("draw", self.expose_event)
+ 		self.thumb_sel_handler = self.thumbpane.get_selection().connect('changed', self.thumbpane_selection_changed)
+ 		self.thumb_scroll_handler = self.thumbscroll.get_vscrollbar().connect("value-changed", self.thumbpane_scrolled)
+ 
+@@ -738,12 +752,12 @@ class Base:
+ 			self.menubar.set_no_show_all(True)
+ 			self.thumbscroll.set_no_show_all(True)
+ 		self.window.show_all()
+-		self.ss_exit.set_size_request(self.ss_start.size_request()[0], self.ss_stop.size_request()[1])
+-		self.ss_randomize.set_size_request(self.ss_start.size_request()[0], -1)
+-		self.ss_start.set_size_request(self.ss_start.size_request()[0]*2, -1)
+-		self.ss_stop.set_size_request(self.ss_stop.size_request()[0]*2, -1)
++		self.ss_exit.set_size_request(self.ss_start.size_request().width, self.ss_stop.size_request().height)
++		self.ss_randomize.set_size_request(self.ss_start.size_request().width, -1)
++		self.ss_start.set_size_request(self.ss_start.size_request().width*2, -1)
++		self.ss_stop.set_size_request(self.ss_stop.size_request().width*2, -1)
+ 		self.UIManager.get_widget('/Popup/Exit Full Screen').hide()
+-		self.layout.set_flags(gtk.CAN_FOCUS)
++		self.layout.set_can_focus(True)
+ 		self.window.set_focus(self.layout)
+ 		
+ 		#sets the visibility of some menu entries
+@@ -758,7 +772,7 @@ class Base:
+ 		self.image_list = []
+ 		if args != []:
+ 			for i in range(len(args)):
+-				args[i] = urllib.url2pathname(args[i])
++				args[i] = urllib.request.url2pathname(args[i])
+ 			self.expand_filelist_and_load_image(args)
+ 		else:
+ 			self.set_go_sensitivities(False)
+@@ -769,13 +783,30 @@ class Base:
+ 				if o in ("-s", "--slideshow"):
+ 					self.toggle_slideshow(None)
+ 
++	def modify_bg(self, widget, gdkcolor):
++		if gdkcolor is None:
++			gdkcolor = gdk.Color(0,0,0)
++		#rgbcolor = gdkcolor.red * 65536 * 65536 + gdkcolor.green * 65536 + gdkcolor.blue
++		rgbcolor = (gdkcolor.red // 256) * 65536
++		rgbcolor += (gdkcolor.green // 256) * 256
++		rgbcolor += (gdkcolor.blue// 256)
++		style_context = widget.get_style_context()
++		style_css = b"""
++		* {
++			background: #%06x;
++		}
++		""" %rgbcolor
++		cssprovider = gtk.CssProvider.new()
++		cssprovider.load_from_data(style_css)
++		style_context.add_provider(cssprovider,  gtk.STYLE_PROVIDER_PRIORITY_USER)
++
+ 	def refresh_recent_files_menu(self):
+ 		if self.merge_id_recent:
+ 			self.UIManager.remove_ui(self.merge_id_recent)
+ 		if self.actionGroupRecent:
+ 			self.UIManager.remove_action_group(self.actionGroupRecent)
+ 			self.actionGroupRecent = None
+-		self.actionGroupRecent = gtk.ActionGroup('RecentFiles')
++		self.actionGroupRecent = gtk.ActionGroup(name='RecentFiles')
+ 		self.UIManager.ensure_update()
+ 		for i in range(len(self.recentfiles)):
+ 			if len(self.recentfiles[i]) > 0:
+@@ -812,7 +843,7 @@ class Base:
+ 		if self.actionGroupCustom:
+ 			self.UIManager.remove_action_group(self.actionGroupCustom)
+ 			self.actionGroupCustom = None
+-		self.actionGroupCustom = gtk.ActionGroup('CustomActions')
++		self.actionGroupCustom = gtk.ActionGroup(name='CustomActions')
+ 		self.UIManager.ensure_update()
+ 		for i in range(len(self.action_names)):
+ 			action = [(self.action_names[i], None, self.action_names[i], self.action_shortcuts[i], None, self.custom_action_click)]
+@@ -843,9 +874,12 @@ class Base:
+ 			self.thumbpane_bottom_coord_loaded = bottom_coord
+ 		# update images:
+ 		if not self.thumbpane_updating:
+-			thread = threading.Thread(target=self.thumbpane_update_pending_images, args=(force_upto_imgnum, None))
+-			thread.setDaemon(True)
+-			thread.start()
++			#thread = threading.Thread(target=self.thumbpane_update_pending_images, args=(force_upto_imgnum, None))
++			#thread.setDaemon(True)
++			#thread.start()
++			#self.thumbpane_update_pending_images(force_upto_imgnum, None)
++			# No, GTK does not allow updating widget from other thread
++			GLib.idle_add(self.thumbpane_update_pending_images, force_upto_imgnum, None)
+ 
+ 	def thumbpane_create_dir(self):
+ 		if not os.path.exists(os.path.expanduser('~/.thumbnails/')):
+@@ -853,6 +887,10 @@ class Base:
+ 		if not os.path.exists(os.path.expanduser('~/.thumbnails/normal/')):
+ 			os.mkdir(os.path.expanduser('~/.thumbnails/normal/'))
+ 
++	def tree_view_get_background_area(self, treeview, ipath, column):
++		treepath = gtk.TreePath.new_from_indices((ipath, -1))
++		return treeview.get_background_area(treepath, column)
++
+ 	def thumbpane_update_pending_images(self, force_upto_imgnum, foo):
+ 		self.thumbpane_updating = True
+ 		self.thumbpane_create_dir()
+@@ -865,11 +903,12 @@ class Base:
+ 			if imgnum >= len(self.image_list):
+ 				break
+ 			self.thumbpane_set_image(self.image_list[imgnum], imgnum)
+-			curr_coord += self.thumbpane.get_background_area((imgnum,),self.thumbcolumn).height
++			#curr_coord += self.thumbpane.get_background_area((imgnum,),self.thumbcolumn).height
++			curr_coord += self.tree_view_get_background_area(self.thumbpane, imgnum, self.thumbcolumn).height
+ 			if force_upto_imgnum == imgnum:
+ 				# Verify that the user hasn't switched images while we're loading thumbnails:
+ 				if force_upto_imgnum == self.curr_img_in_list:
+-					gobject.idle_add(self.thumbpane_select, force_upto_imgnum)
++					GLib.idle_add(self.thumbpane_select, force_upto_imgnum)
+ 			imgnum += 1
+ 		self.thumbpane_updating = False
+ 	
+@@ -891,7 +930,7 @@ class Base:
+ 				if pix:
+ 					if self.thumbnail_size != 128:
+ 						# 128 is the size of the saved thumbnail, so convert if different:
+-						pix, image_width, image_height = self.get_pixbuf_of_size(pix, self.thumbnail_size, gtk.gdk.INTERP_TILES)
++						pix, image_width, image_height = self.get_pixbuf_of_size(pix, self.thumbnail_size, GdkPixbuf.InterpType.TILES)
+ 					self.thumbnail_loaded[imgnum] = True
+ 					self.thumbscroll.get_vscrollbar().handler_block(self.thumb_scroll_handler)
+ 					pix = self.pixbuf_add_border(pix)
+@@ -903,12 +942,12 @@ class Base:
+ 	
+ 	def thumbnail_get_name(self, image_name):
+ 		filename = os.path.expanduser('file://' + image_name)
+-		uriname = os.path.expanduser('file://' + urllib.pathname2url(image_name))
++		uriname = os.path.expanduser('file://' + urllib.request.pathname2url(image_name))
+ 		if HAS_HASHLIB:
+ 		    m = hashlib.md5()
+ 		else:
+ 		    m = md5.new()
+-		m.update(uriname)
++		m.update(uriname.encode('utf-8'))
+ 		mhex = m.hexdigest()
+ 		mhex_filename = os.path.expanduser('~/.thumbnails/normal/' + mhex + '.png')
+ 		return filename, mhex_filename
+@@ -922,7 +961,7 @@ class Base:
+ 			imgfile = imgfile[7:]
+ 		try:
+ 			if os.path.exists(thumb_url) and not force_generation:
+-				pix = gtk.gdk.pixbuf_new_from_file(thumb_url)
++				pix = GdkPixbuf.Pixbuf.new_from_file(thumb_url)
+ 				pix_mtime = pix.get_option('tEXt::Thumb::MTime')
+ 				if pix_mtime:
+ 					st = os.stat(imgfile)
+@@ -931,33 +970,33 @@ class Base:
+ 					if pix_mtime == file_mtime:
+ 						return pix
+ 			# Create the 128x128 thumbnail:
+-			uri = 'file://' + urllib.pathname2url(imgfile)
+-			pix = gtk.gdk.pixbuf_new_from_file(imgfile)
+-			pix, image_width, image_height = self.get_pixbuf_of_size(pix, 128, gtk.gdk.INTERP_TILES)
++			uri = 'file://' + urllib.request.pathname2url(imgfile)
++			pix = GdkPixbuf.Pixbuf.new_from_file(imgfile)
++			pix, image_width, image_height = self.get_pixbuf_of_size(pix, 128, GdkPixbuf.InterpType.TILES)
+ 			st = os.stat(imgfile)
+ 			file_mtime = str(st[stat.ST_MTIME])
+ 			# Save image to .thumbnails:
+-			pix.save(thumb_url, "png", {'tEXt::Thumb::URI':uri, 'tEXt::Thumb::MTime':file_mtime, 'tEXt::Software':'Mirage' + __version__})
++			pix.savev(filename=thumb_url, type="png", option_keys=['tEXt::Thumb::URI', 'tEXt::Thumb::MTime', 'tEXt::Software', None], option_values=[uri, file_mtime, 'Mirage' + __version__ , None])
+ 			return pix
+ 		except:
+ 			return None
+ 	
+ 	def thumbpane_load_image(self, treeview, imgnum):
+ 		if imgnum != self.curr_img_in_list:
+-			gobject.idle_add(self.goto_image, str(imgnum), None)
++			GLib.idle_add(self.goto_image, str(imgnum), None)
+ 		
+ 	def thumbpane_selection_changed(self, treeview):
+ 		cancel = self.autosave_image()
+ 		if cancel:
+ 			# Revert selection...
+-			gobject.idle_add(self.thumbpane_select, self.curr_img_in_list)
++			GLib.idle_add(self.thumbpane_select, self.curr_img_in_list)
+ 			return True
+ 		try:
+ 			model, paths = self.thumbpane.get_selection().get_selected_rows()
+ 			imgnum = paths[0][0]
+ 			if not self.thumbnail_loaded[imgnum]:
+ 				self.thumbpane_set_image(self.image_list[imgnum], imgnum)
+-			gobject.idle_add(self.thumbpane_load_image, treeview, imgnum)
++			GLib.idle_add(self.thumbpane_load_image, treeview, imgnum)
+ 		except:
+ 			pass
+ 		
+@@ -973,7 +1012,7 @@ class Base:
+ 
+ 	def thumbpane_set_size(self):
+ 		self.thumbcolumn.set_fixed_width(self.thumbpane_get_size())
+-		self.window_resized(None, self.window.allocation, True)
++		self.window_resized(None, self.window.get_allocation(), True)
+ 	
+ 	def thumbpane_get_size(self):
+ 		return int(self.thumbnail_size * 1.3)
+@@ -986,7 +1025,7 @@ class Base:
+ 		# load a humongous icon for a small pix, for example, and will keep the thumbnails
+ 		# from shifting around when they are actually loaded.
+ 		try:
+-			info = gtk.gdk.pixbuf_get_file_info(image)
++			info = GdkPixbuf.Pixbuf.get_file_info(image)
+ 			imgwidth = float(info[1])
+ 			imgheight = float(info[2])
+ 			if imgheight > self.thumbnail_size:
+@@ -999,11 +1038,11 @@ class Base:
+ 		except:
+ 			imgheight = 2 + self.thumbnail_size
+ 			imgwidth = self.thumbnail_size
+-		blank_pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, imgwidth, imgheight)
++		blank_pix = GdkPixbuf.Pixbuf.new(colorspace=GdkPixbuf.Colorspace.RGB, has_alpha=True, bits_per_sample=8, width=imgwidth, height=imgheight)
+ 		blank_pix.fill(0x00000000)
+ 		imgwidth2 = int(imgheight*0.8)
+ 		imgheight2 = int(imgheight*0.8)
+-		composite_pix = self.blank_image.scale_simple(imgwidth2, imgheight2, gtk.gdk.INTERP_BILINEAR)
++		composite_pix = self.blank_image.scale_simple(imgwidth2, imgheight2, GdkPixbuf.InterpType.BILINEAR)
+ 		leftcoord = int((imgwidth - imgwidth2)/2)
+ 		topcoord = int((imgheight - imgheight2)/2)
+ 		composite_pix.copy_area(0, 0, imgwidth2, imgheight2, blank_pix, leftcoord, topcoord)
+@@ -1035,7 +1074,7 @@ class Base:
+ 				return pix
+ 		# If we reached here, we didn't find the pixmap
+ 		if exit_on_fail:
+-			print _("Couldn't find the image %s. Please check your installation.") % filename
++			print (_("Couldn't find the image %s. Please check your installation.") % filename)
+ 			sys.exit(1)
+ 		else:
+ 			return None
+@@ -1064,11 +1103,11 @@ class Base:
+ 	def topwindow_keypress(self, widget, event):
+ 		# For whatever reason, 'Left' and 'Right' cannot be used as menu
+ 		# accelerators so we will manually check for them here:
+-		if (not (event.state & gtk.gdk.SHIFT_MASK)) and not (event.state & gtk.gdk.CONTROL_MASK) and not (event.state & gtk.gdk.MOD1_MASK) and not (event.state & gtk.gdk.MOD2_MASK) and not (event.state & gtk.gdk.CONTROL_MASK):
+-			if event.keyval == gtk.gdk.keyval_from_name('Left') or event.keyval == gtk.gdk.keyval_from_name('Up'):
++		if (not (event.state & gdk.ModifierType.SHIFT_MASK)) and not (event.state & gdk.ModifierType.CONTROL_MASK) and not (event.state & gdk.ModifierType.MOD1_MASK) and not (event.state & gdk.ModifierType.MOD2_MASK) and not (event.state & gdk.ModifierType.CONTROL_MASK):
++			if event.keyval == gdk.keyval_from_name('Left') or event.keyval == gdk.keyval_from_name('Up'):
+ 				self.goto_prev_image(None)
+ 				return
+-			elif event.keyval == gtk.gdk.keyval_from_name('Right') or event.keyval == gtk.gdk.keyval_from_name('Down'):
++			elif event.keyval == gdk.keyval_from_name('Right') or event.keyval == gdk.keyval_from_name('Down'):
+ 				self.goto_next_image(None)
+ 				return
+ 		shortcut = gtk.accelerator_name(event.keyval, event.state)
+@@ -1082,7 +1121,7 @@ class Base:
+ 
+ 	def parse_action_command(self, command, batchmode):
+ 		self.running_custom_actions = True
+-		self.change_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
++		self.change_cursor(gdk.Cursor(gdk.CursorType.WATCH))
+ 		while gtk.events_pending():
+ 			gtk.main_iteration()
+ 		self.curr_custom_action = 0
+@@ -1109,7 +1148,7 @@ class Base:
+ 			self.currimg_pixbuf_original = None
+ 			self.image_load_failed(False)
+ 		else:
+-			animtest = gtk.gdk.PixbufAnimation(self.currimg_name)
++			animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.currimg_name)
+ 			if animtest.is_static_image():
+ 				if self.images_are_different(animtest.get_static_image(), self.currimg_pixbuf_original):
+ 					self.load_new_image2(False, False, True, False)
+@@ -1123,34 +1162,34 @@ class Base:
+ 		if not os.path.exists(self.preloadimg_prev_name):
+ 			self.preloadimg_prev_in_list = -1
+ 		else:
+-			animtest = gtk.gdk.PixbufAnimation(self.preloadimg_prev_name)
++			animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.preloadimg_prev_name)
+ 			if animtest.is_static_image():
+ 				if self.images_are_different(animtest.get_static_image(), self.preloadimg_prev_pixbuf_original):
+ 					self.preloadimg_prev_in_list = -1
+-					self.preload_when_idle = gobject.idle_add(self.preload_prev_image, False)
++					self.preload_when_idle = GLib.idle_add(self.preload_prev_image, False)
+ 			else:
+ 				if self.images_are_different(animtest, self.preloadimg_prev_pixbuf_original):
+ 					self.preloadimg_prev_in_list = -1
+-					self.preload_when_idle = gobject.idle_add(self.preload_prev_image, False)
++					self.preload_when_idle = GLib.idle_add(self.preload_prev_image, False)
+ 		if not os.path.exists(self.preloadimg_next_name):
+ 			self.preloadimg_next_in_list = -1
+ 		else:
+-			animtest = gtk.gdk.PixbufAnimation(self.preloadimg_next_name)
++			animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.preloadimg_next_name)
+ 			if animtest.is_static_image():
+ 				if self.images_are_different(animtest.get_static_image(), self.preloadimg_next_pixbuf_original):
+ 					self.preloadimg_next_in_list = -1
+-					self.preload_when_idle = gobject.idle_add(self.preload_next_image, False)
++					self.preload_when_idle = GLib.idle_add(self.preload_next_image, False)
+ 			else:
+ 				if self.images_are_different(animtest, self.preloadimg_next_pixbuf_original):
+ 					self.preloadimg_next_in_list = -1
+-					self.preload_when_idle = gobject.idle_add(self.preload_next_image, False)
++					self.preload_when_idle = GLib.idle_add(self.preload_next_image, False)
+ 		self.stop_now = False
+ 		if batchmode:
+ 			# Update all thumbnails:
+-			gobject.idle_add(self.thumbpane_update_images, True, self.curr_img_in_list)
++			GLib.idle_add(self.thumbpane_update_images, True, self.curr_img_in_list)
+ 		else:
+ 			# Update only the current thumbnail:
+-			gobject.idle_add(self.thumbpane_set_image, self.image_list[self.curr_img_in_list], self.curr_img_in_list, True)
++			GLib.idle_add(self.thumbpane_set_image, self.image_list[self.curr_img_in_list], self.curr_img_in_list, True)
+ 
+ 	def images_are_different(self, pixbuf1, pixbuf2):
+ 		if pixbuf1.get_pixels() == pixbuf2.get_pixels():
+@@ -1256,13 +1295,13 @@ class Base:
+ 		if "%L" in cmd:
+ 			cmd = cmd.replace("%L", " ".join([sh_esc(s) for s in self.image_list]))
+ 		if self.verbose:
+-			print _("Action: %s") % cmd
++			print (_("Action: %s") % cmd)
+ 		shell_rc = os.system(cmd) >> 8
+ 		if self.verbose:
+-			print _("Action return code: %s") % shell_rc
++			print (_("Action return code: %s") % shell_rc)
+ 		if shell_rc != 0:
+ 			msg = _('Unable to launch \"%s\". Please specify a valid command from Edit > Custom Actions.') % cmd
+-			error_dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, msg)
++			error_dialog = gtk.MessageDialog(self.window, gtk.DialogFlags.MODAL, gtk.MessageType.WARNING, gtk.ButtonsType.CLOSE, msg)
+ 			error_dialog.set_title(_("Invalid Custom Action"))
+ 			error_dialog.run()
+ 			error_dialog.destroy()
+@@ -1305,7 +1344,7 @@ class Base:
+ 		# Only jpeg, png, and bmp images are currently supported for saving
+ 		if len(self.image_list) > 0:
+ 			try:
+-				filetype = gtk.gdk.pixbuf_get_file_info(self.currimg_name)[0]['name']
++				filetype = GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0].get_name()
+ 				self.UIManager.get_widget('/MainMenu/FileMenu/Properties').set_sensitive(True)
+ 				if self.filetype_is_writable(filetype):
+ 					self.UIManager.get_widget('/MainMenu/FileMenu/Save').set_sensitive(enable)
+@@ -1388,55 +1427,55 @@ class Base:
+ 			self.set_zoom_in_sensitivities(False)
+ 
+ 	def print_version(self):
+-		print _("Version: Mirage"), __version__
+-		print _("Website: http://mirageiv.berlios.de")
++		print (_("Version: Mirage"), __version__)
++		print (_("Website: http://mirageiv.berlios.de"))
+ 
+ 	def print_usage(self):
+ 		self.print_version()
+-		print ""
+-		print _("Usage: mirage [OPTION]... FILES|FOLDERS...")
+-		print ""
+-		print _("Options") + ":"
+-		print "  -h, --help           " + _("Show this help and exit")
+-		print "  -v, --version        " + _("Show version information and exit")
+-		print "  -V, --verbose        " + _("Show more detailed information")
+-		print "  -R, --recursive      " + _("Recursively include all images found in")
+-		print "                       " + _("subdirectories of FOLDERS")
+-		print "  -s, --slideshow      " + _("Start in slideshow mode")
+-		print "  -f, --fullscreen     " + _("Start in fullscreen mode")
+-		print "  -o, --onload 'cmd'   " + _("Execute 'cmd' when an image is loaded")
+-		print "                       " + _("uses same syntax as custom actions,\n")
+-		print "                       " + _("i.e. mirage -o 'echo file is %F'")
++		print ("")
++		print (_("Usage: mirage [OPTION]... FILES|FOLDERS..."))
++		print ("")
++		print (_("Options") + ":")
++		print ("  -h, --help           " + _("Show this help and exit"))
++		print ("  -v, --version        " + _("Show version information and exit"))
++		print ("  -V, --verbose        " + _("Show more detailed information"))
++		print ("  -R, --recursive      " + _("Recursively include all images found in"))
++		print ("                       " + _("subdirectories of FOLDERS"))
++		print ("  -s, --slideshow      " + _("Start in slideshow mode"))
++		print ("  -f, --fullscreen     " + _("Start in fullscreen mode"))
++		print ("  -o, --onload 'cmd'   " + _("Execute 'cmd' when an image is loaded"))
++		print ("                       " + _("uses same syntax as custom actions,\n"))
++		print ("                       " + _("i.e. mirage -o 'echo file is %F'"))
+ 
+ 	def delay_changed(self, action):
+ 		self.curr_slideshow_delay = self.ss_delayspin.get_value()
+ 		if self.slideshow_mode:
+-			gobject.source_remove(self.timer_delay)
++			self.source_try_remove(self.timer_delay)
+ 			if self.curr_slideshow_random:
+-				self.timer_delay = gobject.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_random_image, "ss")
++				self.timer_delay = GLib.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_random_image, "ss")
+ 			else:
+-				self.timer_delay = gobject.timeout_add((self.curr_slideshow_delay*1000), self.goto_next_image, "ss")
++				self.timer_delay = GLib.timeout_add((self.curr_slideshow_delay*1000), self.goto_next_image, "ss")
+ 		self.window.set_focus(self.layout)
+ 
+ 	def random_changed(self, action):
+ 		self.curr_slideshow_random = self.ss_randomize.get_active()
+ 
+ 	def motion_cb(self, widget, context, x, y, time):
+-		context.drag_status(gtk.gdk.ACTION_COPY, time)
++		gdk.drag_status(context, gdk.DragAction.COPY, time)
+ 		return True
+ 
+ 	def drop_cb(self, widget, context, x, y, selection, info, time):
+-		uri = selection.data.strip()
+-		path = urllib.url2pathname(uri)
++		uri = selection.get_data().strip()
++		path = urllib.request.url2pathname(uri.decode('utf-8'))
+ 		paths = path.rsplit('\n')
+ 		for i, path in enumerate(paths):
+ 			paths[i] = path.rstrip('\r')
+ 		self.expand_filelist_and_load_image(paths)
+ 
+ 	def put_error_image_to_window(self):
+-		self.imageview.set_from_stock(gtk.STOCK_MISSING_IMAGE, gtk.ICON_SIZE_LARGE_TOOLBAR)
+-		self.currimg_width = self.imageview.size_request()[0]
+-		self.currimg_height = self.imageview.size_request()[1]
++		self.imageview.set_from_stock(gtk.STOCK_MISSING_IMAGE, gtk.IconSize.LARGE_TOOLBAR)
++		self.currimg_width = self.imageview.size_request().width
++		self.currimg_height = self.imageview.size_request().height
+ 		self.center_image()
+ 		self.set_go_sensitivities(False)
+ 		self.set_image_sensitivities(False)
+@@ -1444,7 +1483,8 @@ class Base:
+ 		self.loaded_img_in_list = -1
+ 		return
+ 
+-	def expose_event(self, widget, event):
++	# FIXME
++	def expose_event(self, widget, cr):
+ 		if self.updating_adjustments:
+ 			return
+ 		self.updating_adjustments = True
+@@ -1480,63 +1520,70 @@ class Base:
+ 				self.load_new_image_stop_now()
+ 				self.show_scrollbars_if_needed()
+ 				# Also, regenerate preloaded image for new window size:
+-				self.preload_when_idle = gobject.idle_add(self.preload_next_image, True)
+-				self.preload_when_idle2 = gobject.idle_add(self.preload_prev_image, True)
++				self.preload_when_idle = GLib.idle_add(self.preload_next_image, True)
++				self.preload_when_idle2 = GLib.idle_add(self.preload_prev_image, True)
+ 		self.prevwinwidth = allocation.width
+ 		self.prevwinheight = allocation.height
+ 		return
+ 
++	def conf_set(self, conf, section, item, value):
++		if not isinstance(value, str):
++			conf.set(section, item, str(value))
++		else:
++			conf.set(section, item, value)
++
+ 	def save_settings(self):
+-		conf = ConfigParser.ConfigParser()
++		conf = configparser.ConfigParser(interpolation=None)
+ 		conf.add_section('window')
+-		conf.set('window', 'w', self.window.get_allocation().width)
+-		conf.set('window', 'h', self.window.get_allocation().height)
+-		conf.set('window', 'toolbar', self.toolbar_show)
+-		conf.set('window', 'statusbar', self.statusbar_show)
+-		conf.set('window', 'thumbpane', self.thumbpane_show)
++		self.conf_set(conf, 'window', 'w', self.window.get_allocation().width)
++		self.conf_set(conf, 'window', 'h', self.window.get_allocation().height)
++		self.conf_set(conf, 'window', 'toolbar', self.toolbar_show)
++		self.conf_set(conf, 'window', 'statusbar', self.statusbar_show)
++		self.conf_set(conf, 'window', 'thumbpane', self.thumbpane_show)
+ 		conf.add_section('prefs')
+-		conf.set('prefs', 'simple-bgcolor', self.simple_bgcolor)
+-		conf.set('prefs', 'bgcolor-red', self.bgcolor.red)
+-		conf.set('prefs', 'bgcolor-green', self.bgcolor.green)
+-		conf.set('prefs', 'bgcolor-blue', self.bgcolor.blue)
+-		conf.set('prefs', 'open_all', self.open_all_images)
+-		conf.set('prefs', 'hidden', self.open_hidden_files)
+-		conf.set('prefs', 'use_last_dir', self.use_last_dir)
+-		conf.set('prefs', 'last_dir', self.last_dir)
+-		conf.set('prefs', 'fixed_dir', self.fixed_dir)
+-		conf.set('prefs', 'open_mode', self.open_mode)
+-		conf.set('prefs', 'last_mode', self.last_mode)
+-		conf.set('prefs', 'listwrap_mode', self.listwrap_mode)
+-		conf.set('prefs', 'slideshow_delay', int(self.slideshow_delay))
+-		conf.set('prefs', 'slideshow_random', self.slideshow_random)
+-		conf.set('prefs', 'zoomquality', self.zoomvalue)
+-		conf.set('prefs', 'quality_save', int(self.quality_save))
+-		conf.set('prefs', 'disable_screensaver', self.disable_screensaver)
+-		conf.set('prefs', 'slideshow_in_fullscreen', self.slideshow_in_fullscreen)
+-		conf.set('prefs', 'confirm_delete', self.confirm_delete)
+-		conf.set('prefs', 'preloading_images', self.preloading_images)
+-		conf.set('prefs', 'savemode', self.savemode)
+-		conf.set('prefs', 'start_in_fullscreen', self.start_in_fullscreen)
+-		conf.set('prefs', 'thumbsize', self.thumbnail_size)
+-		conf.set('prefs', 'screenshot_delay', self.screenshot_delay)
++		self.conf_set(conf, 'prefs', 'simple-bgcolor', self.simple_bgcolor)
++		self.conf_set(conf, 'prefs', 'bgcolor-red', self.bgcolor.red)
++		self.conf_set(conf, 'prefs', 'bgcolor-green', self.bgcolor.green)
++		self.conf_set(conf, 'prefs', 'bgcolor-blue', self.bgcolor.blue)
++		self.conf_set(conf, 'prefs', 'open_all', self.open_all_images)
++		self.conf_set(conf, 'prefs', 'hidden', self.open_hidden_files)
++		self.conf_set(conf, 'prefs', 'use_last_dir', self.use_last_dir)
++		self.conf_set(conf, 'prefs', 'last_dir', self.last_dir)
++		self.conf_set(conf, 'prefs', 'fixed_dir', self.fixed_dir)
++		self.conf_set(conf, 'prefs', 'open_mode', self.open_mode)
++		self.conf_set(conf, 'prefs', 'last_mode', self.last_mode)
++		self.conf_set(conf, 'prefs', 'listwrap_mode', self.listwrap_mode)
++		self.conf_set(conf, 'prefs', 'slideshow_delay', int(self.slideshow_delay))
++		self.conf_set(conf, 'prefs', 'slideshow_random', self.slideshow_random)
++		self.conf_set(conf, 'prefs', 'zoomquality', self.zoomvalue)
++		self.conf_set(conf, 'prefs', 'quality_save', int(self.quality_save))
++		self.conf_set(conf, 'prefs', 'disable_screensaver', self.disable_screensaver)
++		self.conf_set(conf, 'prefs', 'slideshow_in_fullscreen', self.slideshow_in_fullscreen)
++		self.conf_set(conf, 'prefs', 'confirm_delete', self.confirm_delete)
++		self.conf_set(conf, 'prefs', 'preloading_images', self.preloading_images)
++		self.conf_set(conf, 'prefs', 'savemode', self.savemode)
++		self.conf_set(conf, 'prefs', 'start_in_fullscreen', self.start_in_fullscreen)
++		self.conf_set(conf, 'prefs', 'thumbsize', self.thumbnail_size)
++		self.conf_set(conf, 'prefs', 'screenshot_delay', self.screenshot_delay)
+ 		conf.add_section('actions')
+-		conf.set('actions', 'num_actions', len(self.action_names))
++		self.conf_set(conf, 'actions', 'num_actions', len(self.action_names))
+ 		for i in range(len(self.action_names)):
+-			conf.set('actions', 'names[' + str(i) + ']', self.action_names[i])
+-			conf.set('actions', 'commands[' + str(i) + ']', self.action_commands[i])
+-			conf.set('actions', 'shortcuts[' + str(i) + ']', self.action_shortcuts[i])
+-			conf.set('actions', 'batch[' + str(i) + ']', self.action_batch[i])
++			self.conf_set(conf, 'actions', 'names[' + str(i) + ']', self.action_names[i])
++			self.conf_set(conf, 'actions', 'commands[' + str(i) + ']', self.action_commands[i])
++			self.conf_set(conf, 'actions', 'shortcuts[' + str(i) + ']', self.action_shortcuts[i])
++			self.conf_set(conf, 'actions', 'batch[' + str(i) + ']', self.action_batch[i])
+ 		conf.add_section('recent')
+-		conf.set('recent', 'num_recent', len(self.recentfiles))
++		self.conf_set(conf, 'recent', 'num_recent', len(self.recentfiles))
+ 		for i in range(len(self.recentfiles)):
+-			conf.set('recent', 'num[' + str(i) + ']', len(self.recentfiles[i]))
+-			conf.set('recent', 'urls[' + str(i) + ',0]', self.recentfiles[i])
++			self.conf_set(conf, 'recent', 'num[' + str(i) + ']', len(self.recentfiles[i]))
++			self.conf_set(conf, 'recent', 'urls[' + str(i) + ',0]', self.recentfiles[i])
+ 		if not os.path.exists(self.config_dir):
+ 			os.makedirs(self.config_dir)
+-		conf.write(file(self.config_dir + '/miragerc', 'w'))
++		with open(self.config_dir + '/miragerc', 'w') as configfile:
++			conf.write(configfile)
+ 
+ 		# Also, save accel_map:
+-		gtk.accel_map_save(self.config_dir + '/accel_map')
++		gtk.AccelMap.save(self.config_dir + '/accel_map')
+ 
+ 		return
+ 
+@@ -1567,7 +1614,7 @@ class Base:
+ 		sys.exit(0)
+ 
+ 	def put_zoom_image_to_window(self, currimg_preloaded):
+-		self.window.window.freeze_updates()
++		self.window.get_window().freeze_updates()
+ 		if not currimg_preloaded:
+ 			# Always start with the original image to preserve quality!
+ 			# Calculate image size:
+@@ -1578,10 +1625,11 @@ class Base:
+ 				if not self.currimg_pixbuf_original.get_has_alpha():
+ 					self.currimg_pixbuf = self.currimg_pixbuf_original.scale_simple(finalimg_width, finalimg_height, self.zoom_quality)
+ 				else:
+-					colormap = self.imageview.get_colormap()
+-					light_grey = colormap.alloc_color('#666666', True, True)
+-					dark_grey = colormap.alloc_color('#999999', True, True)
+-					self.currimg_pixbuf = self.currimg_pixbuf_original.composite_color_simple(finalimg_width, finalimg_height, self.zoom_quality, 255, 8, light_grey.pixel, dark_grey.pixel)
++					#colormap = self.imageview.get_colormap()
++					#light_grey = colormap.alloc_color('#666666', True, True)
++					#dark_grey = colormap.alloc_color('#999999', True, True)
++					#self.currimg_pixbuf = self.currimg_pixbuf_original.composite_color_simple(finalimg_width, finalimg_height, self.zoom_quality, 255, 8, light_grey.pixel, dark_grey.pixel)
++					self.currimg_pixbuf = self.currimg_pixbuf_original.composite_color_simple(finalimg_width, finalimg_height, self.zoom_quality, 255, 8, 0x666666, 0x999999)
+ 			else:
+ 				self.currimg_pixbuf = self.currimg_pixbuf_original
+ 			self.currimg_width, self.currimg_height = finalimg_width, finalimg_height
+@@ -1596,7 +1644,7 @@ class Base:
+ 			self.previmage_is_animation = True
+ 		# Clean up (free memory) because I'm lazy
+ 		gc.collect()
+-		self.window.window.thaw_updates()
++		self.window.get_window().thaw_updates()
+ 		self.loaded_img_in_list = self.curr_img_in_list
+ 
+ 	def show_scrollbars_if_needed(self):
+@@ -1622,33 +1670,34 @@ class Base:
+ 		width = self.window.get_size()[0]
+ 		if not self.fullscreen_mode:
+ 			if self.thumbpane_show:
+-				width -= self.thumbscroll.size_request()[0]
++				width -= self.thumbscroll.size_request().width
+ 		return width
+ 
+ 	def available_image_height(self):
+ 		height = self.window.get_size()[1]
+ 		if not self.fullscreen_mode:
+-			height -= self.menubar.size_request()[1]
++			height -= self.menubar.size_request().height
+ 			if self.toolbar_show:
+-				height -= self.toolbar.size_request()[1]
++				height -= self.toolbar.size_request().height
+ 			if self.statusbar_show:
+-				height -= self.statusbar.size_request()[1]
++				height -= self.statusbar.size_request().height
+ 		return height
+ 
+ 	def save_image(self, action):
+ 		if self.UIManager.get_widget('/MainMenu/FileMenu/Save').get_property('sensitive'):
+-			self.save_image_now(self.currimg_name, gtk.gdk.pixbuf_get_file_info(self.currimg_name)[0]['name'])
++			self.save_image_now(self.currimg_name, GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0].get_name())
+ 
+ 	def save_image_as(self, action):
+-		dialog = gtk.FileChooserDialog(title=_("Save As"),action=gtk.FILE_CHOOSER_ACTION_SAVE,buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
+-		dialog.set_default_response(gtk.RESPONSE_OK)
++		dialog = gtk.FileChooserDialog(title=_("Save As"),action=gtk.FileChooserAction.SAVE)
++		dialog.add_buttons(gtk.STOCK_CANCEL,gtk.ResponseType.CANCEL,gtk.STOCK_SAVE,gtk.ResponseType.OK)
++		dialog.set_default_response(gtk.ResponseType.OK)
+ 		filename = os.path.basename(self.currimg_name)
+ 		filetype = None
+ 		dialog.set_current_folder(os.path.dirname(self.currimg_name))
+ 		dialog.set_current_name(filename)
+ 		dialog.set_do_overwrite_confirmation(True)
+ 		response = dialog.run()
+-		if response == gtk.RESPONSE_OK:
++		if response == gtk.ResponseType.OK:
+ 			prev_name = self.currimg_name
+ 			filename = dialog.get_filename()
+ 			dialog.destroy()
+@@ -1656,9 +1705,9 @@ class Base:
+ 			if len(fileext) > 0:
+ 				fileext = fileext[1:]
+ 			# Override filetype if user typed a filename with a different extension:
+-			for i in gtk.gdk.pixbuf_get_formats():
+-				if fileext in i['extensions']:
+-					filetype = i['name']
++			for i in GdkPixbuf.Pixbuf.get_formats():
++				if fileext in i.get_extensions():
++					filetype = i.get_name()
+ 			self.save_image_now(filename, filetype)
+ 			self.register_file_with_recent_docs(filename)
+ 		else:
+@@ -1666,25 +1715,25 @@ class Base:
+ 			
+ 	def save_image_now(self, dest_name, filetype):
+ 		try:
+-			self.change_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
++			self.change_cursor(gdk.Cursor(gdk.CursorType.WATCH))
+ 			while gtk.events_pending():
+ 				gtk.main_iteration()
+ 			if filetype == None:
+-				filetype = gtk.gdk.pixbuf_get_file_info(self.currimg_name)[0]['name']
++				filetype = GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0].get_name()
+ 			if self.filetype_is_writable(filetype):
+-				self.currimg_pixbuf_original.save(dest_name, filetype, {'quality': str(self.quality_save)})
++				self.currimg_pixbuf_original.savev(filename=dest_name, type=filetype, option_keys=['quality', None], option_values=[str(self.quality_save), None])
+ 				self.currimg_name = dest_name
+ 				self.image_list[self.curr_img_in_list] = dest_name
+ 				self.update_title()
+ 				self.update_statusbar()
+ 				# Update thumbnail:
+-				gobject.idle_add(self.thumbpane_set_image, dest_name, self.curr_img_in_list, True)
++				GLib.idle_add(self.thumbpane_set_image, dest_name, self.curr_img_in_list, True)
+ 				self.image_modified = False
+ 			else:
+-				error_dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _('The %s format is not supported for saving. Do you wish to save the file in a different format?') % filetype)
++				error_dialog = gtk.MessageDialog(parent=self.window, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.YES_NO, text=_('The %s format is not supported for saving. Do you wish to save the file in a different format?') % filetype)
+ 				error_dialog.set_title(_("Save"))
+ 				response = error_dialog.run()
+-				if response == gtk.RESPONSE_YES:
++				if response == gtk.ResponseType.YES:
+ 					error_dialog.destroy()
+ 					while gtk.events_pending():
+ 						gtk.main_iteration()
+@@ -1692,7 +1741,7 @@ class Base:
+ 				else:
+ 					error_dialog.destroy()
+ 		except:
+-			error_dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _('Unable to save %s') % dest_name)
++			error_dialog = gtk.MessageDialog(parent=self.window, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.CLOSE, text=_('Unable to save %s') % dest_name)
+ 			error_dialog.set_title(_("Save"))
+ 			error_dialog.run()
+ 			error_dialog.destroy()
+@@ -1709,21 +1758,21 @@ class Base:
+ 				self.save_image(None)
+ 				self.UIManager.get_widget('/MainMenu/FileMenu/Save').set_property('sensitive', temp)
+ 			elif self.savemode == 2:
+-				dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("The current image has been modified. Save changes?"))
+-				dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+-				dialog.add_button(gtk.STOCK_NO, gtk.RESPONSE_NO)
+-				dialog.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_YES)
++				dialog = gtk.MessageDialog(parent=self.window, modal=True, destroy_with_parent=True, message_type=gtk.MessageType.QUESTION, buttons=gtk.ButtonsType.NONE, text=_("The current image has been modified. Save changes?"))
++				dialog.add_button(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL)
++				dialog.add_button(gtk.STOCK_NO, gtk.ResponseType.NO)
++				dialog.add_button(gtk.STOCK_SAVE, gtk.ResponseType.YES)
+ 				dialog.set_title(_("Save?"))
+-				dialog.set_default_response(gtk.RESPONSE_YES)
++				dialog.set_default_response(gtk.ResponseType.YES)
+ 				response = dialog.run()
+ 				dialog.destroy()
+-				if response == gtk.RESPONSE_YES:
++				if response == gtk.ResponseType.YES:
+ 					temp = self.UIManager.get_widget('/MainMenu/FileMenu/Save').get_property('sensitive')
+ 					self.UIManager.get_widget('/MainMenu/FileMenu/Save').set_property('sensitive', True)
+ 					self.save_image(None)
+ 					self.UIManager.get_widget('/MainMenu/FileMenu/Save').set_property('sensitive', temp)
+ 					self.image_modified = False
+-				elif response == gtk.RESPONSE_NO:
++				elif response == gtk.ResponseType.NO:
+ 					self.image_modified = False
+ 					# Ensures that we don't use the current pixbuf for any preload pixbufs if we are in
+ 					# the process of loading the previous or next image in the list:
+@@ -1737,9 +1786,9 @@ class Base:
+ 	def filetype_is_writable(self, filetype):
+ 		# Determine if filetype is a writable format
+ 		filetype_is_writable = True
+-		for i in gtk.gdk.pixbuf_get_formats():
+-			if filetype in i['extensions']:
+-				if i['is_writable']:
++		for i in GdkPixbuf.Pixbuf.get_formats():
++			if filetype in i.get_extensions():
++				if i.is_writable():
+ 					return True
+ 		return False
+ 
+@@ -1751,21 +1800,22 @@ class Base:
+ 	
+ 	def open_file_remote(self, action):
+ 		# Prompt user for the url:
+-		dialog = gtk.Dialog(_("Open Remote"), self.window, gtk.DIALOG_MODAL, buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
++		dialog = gtk.Dialog(title=_("Open Remote"), parent=self.window, modal=True)
++		dialog.add_buttons(gtk.STOCK_CANCEL,gtk.ResponseType.CANCEL,gtk.STOCK_OPEN,gtk.ResponseType.OK)
+ 		location = gtk.Entry()
+ 		location.set_size_request(300, -1)
+ 		location.set_activates_default(True)
+ 		hbox = gtk.HBox()
+-		hbox.pack_start(gtk.Label(_("Image Location (URL):")), False, False, 5)
++		hbox.pack_start(gtk.Label(label=_("Image Location (URL):")), False, False, 5)
+ 		hbox.pack_start(location, True, True, 5)
+ 		dialog.vbox.pack_start(hbox, True, True, 10)
+-		dialog.set_default_response(gtk.RESPONSE_OK)
++		dialog.set_default_response(gtk.ResponseType.OK)
+ 		dialog.vbox.show_all()
+ 		dialog.connect('response', self.open_file_remote_response,  location)
+ 		response = dialog.show()
+ 	
+ 	def open_file_remote_response(self, dialog, response, location):
+-		if response == gtk.RESPONSE_OK:
++		if response == gtk.ResponseType.OK:
+ 			filenames = []
+ 			filenames.append(location.get_text())
+ 			dialog.destroy()
+@@ -1787,7 +1837,8 @@ class Base:
+ 		if cancel:
+ 			return
+ 		# If isfile = True, file; If isfile = False, folder
+-		dialog = gtk.FileChooserDialog(title=_("Open"),action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
++		dialog = gtk.FileChooserDialog(title=_("Open"),action=gtk.FileChooserAction.OPEN)
++		dialog.add_buttons(gtk.STOCK_CANCEL,gtk.ResponseType.CANCEL,gtk.STOCK_OPEN,gtk.ResponseType.OK)
+ 		if isfile:
+ 			filter = gtk.FileFilter()
+ 			filter.set_name(_("Images"))
+@@ -1803,10 +1854,10 @@ class Base:
+ 			dialog.connect("update-preview", self.update_preview, preview)
+ 			recursivebutton = None
+ 		else:
+-			dialog.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
++			dialog.set_action(gtk.FileChooserAction.SELECT_FOLDER)
+ 			recursivebutton = gtk.CheckButton(label=_("Include images in subdirectories"))
+ 			dialog.set_extra_widget(recursivebutton)
+-		dialog.set_default_response(gtk.RESPONSE_OK)
++		dialog.set_default_response(gtk.ResponseType.OK)
+ 		dialog.set_select_multiple(True)
+ 		if self.use_last_dir:
+ 			if self.last_dir != None:
+@@ -1818,7 +1869,7 @@ class Base:
+ 		response = dialog.show()
+ 	
+ 	def open_file_or_folder_response(self, dialog, response, isfile, recursivebutton):
+-		if response == gtk.RESPONSE_OK:
++		if response == gtk.ResponseType.OK:
+ 			if self.use_last_dir:
+ 				self.last_dir = dialog.get_current_folder()
+ 			if not isfile and recursivebutton.get_property('active'):
+@@ -1840,7 +1891,7 @@ class Base:
+ 		if pixbuf:
+ 			preview.set_from_pixbuf(pixbuf)
+ 		else:
+-			pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 1, 8, 128, 128)
++			pixbuf = GdkPixbuf.Pixbuf.new(colorspace=GdkPixbuf.Colorspace.RGB, has_alpha=1, bits_per_sample=8, width=128, height=128)
+ 			pixbuf.fill(0x00000000)
+ 			preview.set_from_pixbuf(pixbuf)
+ 		have_preview = True
+@@ -1850,14 +1901,14 @@ class Base:
+ 
+ 	def hide_cursor(self):
+ 		if self.fullscreen_mode and not self.user_prompt_visible and not self.slideshow_controls_visible:
+-			pix_data = """/* XPM */
+-			static char * invisible_xpm[] = {
++			pix_data_array = [
+ 			"1 1 1 1",
+ 			"       c None",
+-			" "};"""
+-			color = gtk.gdk.Color()
+-			pix = gtk.gdk.pixmap_create_from_data(None, pix_data, 1, 1, 1, color, color)
+-			invisible = gtk.gdk.Cursor(pix, pix, color, color, 0, 0)
++			" "
++			]
++			pixbuf = GdkPixbuf.Pixbuf.new_from_xpm_data(pix_data_array)
++			default_display = gdk.Display.get_default()
++			invisible = gdk.Cursor.new_from_pixbuf(default_display, pixbuf, 0, 0)
+ 			self.change_cursor(invisible)
+ 		return False
+ 
+@@ -1873,20 +1924,22 @@ class Base:
+ 			self.thumbscroll.hide()
+ 			self.thumbpane.hide()
+ 			self.window.fullscreen()
+-			self.timer_id = gobject.timeout_add(2000, self.hide_cursor)
++			self.timer_id = GLib.timeout_add(2000, self.hide_cursor)
+ 			self.set_slideshow_sensitivities()
+ 			if self.simple_bgcolor:
+-				self.layout.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
++				#self.layout.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++				self.modify_bg(self.layout_vbox, self.bgcolor)
+ 		else:
+ 			if self.simple_bgcolor:
+-				self.layout.modify_bg(gtk.STATE_NORMAL, None)
++				#self.layout.modify_bg(gtk.StateType.NORMAL, None)
++				self.modify_bg(self.layout_vbox, None)
+ 			self.leave_fullscreen(action)
+ 
+ 	def leave_fullscreen(self, action):
+ 		if self.fullscreen_mode:
+ 			self.slideshow_controls_visible = False
+-			self.slideshow_window.hide_all()
+-			self.slideshow_window2.hide_all()
++			self.slideshow_window.hide()
++			self.slideshow_window2.hide()
+ 			self.fullscreen_mode = False
+ 			self.UIManager.get_widget('/Popup/Full Screen').show()
+ 			self.UIManager.get_widget('/Popup/Exit Full Screen').hide()
+@@ -1904,7 +1957,8 @@ class Base:
+ 			self.change_cursor(None)
+ 			self.set_slideshow_sensitivities()
+ 			if self.simple_bgcolor:
+-				self.layout.modify_bg(gtk.STATE_NORMAL, None)
++				#self.layout.modify_bg(gtk.StateType.NORMAL, None)
++				self.modify_bg(self.layout_vbox, None)
+ 
+ 	def toggle_status_bar(self, action):
+ 		if self.statusbar.get_property('visible'):
+@@ -1931,7 +1985,7 @@ class Base:
+ 			self.thumbpane.show()
+ 			self.thumbpane_show = True
+ 			self.stop_now = False
+-			gobject.idle_add(self.thumbpane_update_images, True, self.curr_img_in_list)
++			GLib.idle_add(self.thumbpane_update_images, True, self.curr_img_in_list)
+ 		if self.image_loaded and self.last_image_action_was_fit:
+ 			if self.last_image_action_was_smart_fit:
+ 				self.zoom_to_fit_or_1_to_1(None, False, False)
+@@ -1970,10 +2024,10 @@ class Base:
+ 
+ 	def show_custom_actions(self, action):
+ 		self.actions_dialog = gtk.Dialog(title=_("Configure Custom Actions"), parent=self.window)
+-		self.actions_dialog.set_has_separator(False)
++		#self.actions_dialog.set_has_separator(False)
+ 		self.actions_dialog.set_resizable(False)
+-		table_actions = gtk.Table(13, 2, False)
+-		table_actions.attach(gtk.Label(), 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
++		table_actions = gtk.Table(n_rows=13, n_columns=2, homogeneous=False)
++		table_actions.attach(gtk.Label(), 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
+ 		actionscrollwindow = gtk.ScrolledWindow()
+ 		self.actionstore = gtk.ListStore(str, str, str)
+ 		self.actionwidget = gtk.TreeView()
+@@ -1981,8 +2035,8 @@ class Base:
+ 		self.actionwidget.set_rules_hint(True)
+ 		self.actionwidget.connect('row-activated', self.edit_custom_action2)
+ 		actionscrollwindow.add(self.actionwidget)
+-		actionscrollwindow.set_shadow_type(gtk.SHADOW_IN)
+-		actionscrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
++		actionscrollwindow.set_shadow_type(gtk.ShadowType.IN)
++		actionscrollwindow.set_policy(gtk.PolicyType.AUTOMATIC, gtk.PolicyType.AUTOMATIC)
+ 		actionscrollwindow.set_size_request(500, 200)
+ 		self.actionwidget.set_model(self.actionstore)
+ 		self.cell = gtk.CellRendererText()
+@@ -1990,7 +2044,7 @@ class Base:
+ 		self.tvcolumn0 = gtk.TreeViewColumn(_("Batch"))
+ 		self.tvcolumn1 = gtk.TreeViewColumn(_("Action"), self.cell, markup=0)
+ 		self.tvcolumn2 = gtk.TreeViewColumn(_("Shortcut"))
+-		self.tvcolumn1.set_max_width(self.actionwidget.size_request()[0] - self.tvcolumn0.get_width() - self.tvcolumn2.get_width())
++		self.tvcolumn1.set_max_width(self.actionwidget.size_request().width - self.tvcolumn0.get_width() - self.tvcolumn2.get_width())
+ 		self.actionwidget.append_column(self.tvcolumn0)
+ 		self.actionwidget.append_column(self.tvcolumn1)
+ 		self.actionwidget.append_column(self.tvcolumn2)
+@@ -1998,23 +2052,23 @@ class Base:
+ 		if len(self.action_names) > 0:
+ 			self.actionwidget.get_selection().select_path(0)
+ 		vbox_actions = gtk.VBox()
+-		addbutton = gtk.Button("", gtk.STOCK_ADD)
++		addbutton = gtk.Button.new_from_stock(gtk.STOCK_ADD)
+ 		addbutton.get_child().get_child().get_children()[1].set_text('')
+ 		addbutton.connect('clicked', self.add_custom_action, self.actionwidget)
+ 		addbutton.set_tooltip_text(_("Add action"))
+-		editbutton = gtk.Button("", gtk.STOCK_EDIT)
++		editbutton = gtk.Button.new_from_stock(gtk.STOCK_EDIT)
+ 		editbutton.get_child().get_child().get_children()[1].set_text('')
+ 		editbutton.connect('clicked', self.edit_custom_action, self.actionwidget)
+ 		editbutton.set_tooltip_text(_("Edit selected action."))
+-		removebutton = gtk.Button("", gtk.STOCK_REMOVE)
++		removebutton = gtk.Button.new_from_stock(gtk.STOCK_REMOVE)
+ 		removebutton.get_child().get_child().get_children()[1].set_text('')
+ 		removebutton.connect('clicked', self.remove_custom_action)
+ 		removebutton.set_tooltip_text(_("Remove selected action."))
+-		upbutton = gtk.Button("", gtk.STOCK_GO_UP)
++		upbutton = gtk.Button.new_from_stock(gtk.STOCK_GO_UP)
+ 		upbutton.get_child().get_child().get_children()[1].set_text('')
+ 		upbutton.connect('clicked', self.custom_action_move_up, self.actionwidget)
+ 		upbutton.set_tooltip_text(_("Move selected action up."))
+-		downbutton = gtk.Button("", gtk.STOCK_GO_DOWN)
++		downbutton = gtk.Button.new_from_stock(gtk.STOCK_GO_DOWN)
+ 		downbutton.get_child().get_child().get_children()[1].set_text('')
+ 		downbutton.connect('clicked', self.custom_action_move_down, self.actionwidget)
+ 		downbutton.set_tooltip_text(_("Move selected action down."))
+@@ -2040,21 +2094,21 @@ class Base:
+ 		vbox_actions.pack_start(hbox_info, False, False, 5)
+ 		hbox_instructions = gtk.HBox()
+ 		info_image = gtk.Image()
+-		info_image.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON)
++		info_image.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.IconSize.BUTTON)
+ 		hbox_instructions.pack_start(info_image, False, False, 5)
+-		instructions = gtk.Label(_("Here you can define custom actions with shortcuts. Actions use the built-in parameters and operations listed below and can have multiple statements separated by a semicolon. Batch actions apply to all images in the list."))
++		instructions = gtk.Label(label=_("Here you can define custom actions with shortcuts. Actions use the built-in parameters and operations listed below and can have multiple statements separated by a semicolon. Batch actions apply to all images in the list."))
+ 		instructions.set_line_wrap(True)
+ 		instructions.set_alignment(0, 0.5)
+ 		hbox_instructions.pack_start(instructions, False, False, 5)
+-		table_actions.attach(hbox_instructions, 1, 3, 2, 3,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 5, 0)
+-		table_actions.attach(gtk.Label(), 1, 3, 3, 4,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_actions.attach(vbox_actions, 1, 3, 4, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_actions.attach(gtk.Label(), 1, 3, 12, 13,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
++		table_actions.attach(hbox_instructions, 1, 3, 2, 3,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 5, 0)
++		table_actions.attach(gtk.Label(), 1, 3, 3, 4,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_actions.attach(vbox_actions, 1, 3, 4, 12, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_actions.attach(gtk.Label(), 1, 3, 12, 13,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
+ 		self.actions_dialog.vbox.pack_start(table_actions, False, False, 0)
+ 		# Show dialog:
+ 		self.actions_dialog.vbox.show_all()
+-		instructions.set_size_request(self.actions_dialog.size_request()[0]-50, -1)
+-		close_button = self.actions_dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
++		instructions.set_size_request(self.actions_dialog.size_request().width-50, -1)
++		close_button = self.actions_dialog.add_button(gtk.STOCK_CLOSE, gtk.ResponseType.CLOSE)
+ 		close_button.grab_focus()
+ 		self.actions_dialog.run()
+ 		self.refresh_custom_actions_menu()
+@@ -2078,44 +2132,46 @@ class Base:
+ 
+ 	def open_custom_action_dialog(self, add_call, name, command, shortcut, batch, treeview):
+ 		if add_call:
+-			self.dialog_name = gtk.Dialog(_("Add Custom Action"), self.actions_dialog, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
++			self.dialog_name = gtk.Dialog(title=_("Add Custom Action"), parent=self.actions_dialog, modal=True)
++			
+ 		else:
+-			self.dialog_name = gtk.Dialog(_("Edit Custom Action"), self.actions_dialog, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
++			self.dialog_name = gtk.Dialog(title=_("Edit Custom Action"), parent=self.actions_dialog, modal=True)
++		self.dialog_name.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.REJECT, gtk.STOCK_OK, gtk.ResponseType.ACCEPT)
+ 		self.dialog_name.set_modal(True)
+-		table = gtk.Table(2, 4, False)
+-		action_name_label = gtk.Label(_("Action Name:"))
++		table = gtk.Table(n_rows=2, n_columns=4, homogeneous=False)
++		action_name_label = gtk.Label(label=_("Action Name:"))
+ 		action_name_label.set_alignment(0, 0.5)
+-		action_command_label = gtk.Label(_("Command:"))
++		action_command_label = gtk.Label(label=_("Command:"))
+ 		action_command_label.set_alignment(0, 0.5)
+-		shortcut_label = gtk.Label(_("Shortcut:"))
++		shortcut_label = gtk.Label(label=_("Shortcut:"))
+ 		shortcut_label.set_alignment(0, 0.5)
+-		table.attach(action_name_label, 0, 1, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table.attach(action_command_label, 0, 1, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table.attach(shortcut_label, 0, 1, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
++		table.attach(action_name_label, 0, 1, 0, 1, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table.attach(action_command_label, 0, 1, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table.attach(shortcut_label, 0, 1, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
+ 		action_name = gtk.Entry()
+ 		action_name.set_text(name)
+ 		action_command = gtk.Entry()
+ 		action_command.set_text(command)
+-		table.attach(action_name, 1, 2, 0, 1, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table.attach(action_command, 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
++		table.attach(action_name, 1, 2, 0, 1, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table.attach(action_command, 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
+ 		self.shortcut = gtk.Button(shortcut)
+ 		self.shortcut.connect('clicked', self.shortcut_clicked)
+-		table.attach(self.shortcut, 1, 2, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		batchmode = gtk.CheckButton(_("Perform action on all images (Batch)"))
++		table.attach(self.shortcut, 1, 2, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		batchmode = gtk.CheckButton(label=_("Perform action on all images (Batch)"))
+ 		batchmode.set_active(batch)
+-		table.attach(batchmode, 0, 2, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
++		table.attach(batchmode, 0, 2, 3, 4, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
+ 		self.dialog_name.vbox.pack_start(table, False, False, 5)
+ 		self.dialog_name.vbox.show_all()
+ 		self.dialog_name.connect('response', self.dialog_name_response, add_call, action_name, action_command, self.shortcut, batchmode, treeview)
+ 		self.dialog_name.run()
+ 
+ 	def dialog_name_response(self, dialog, response, add_call, action_name, action_command, shortcut, batchmode, treeview):
+-		if response == gtk.RESPONSE_ACCEPT:
++		if response == gtk.ResponseType.ACCEPT:
+ 			if not (action_command.get_text() == "" or action_name.get_text() == "" or self.shortcut.get_label() == "None"):
+ 				name = action_name.get_text()
+ 				command = action_command.get_text()
+ 				if ((("[NEXT]" in command.strip()) and command.strip()[-6:] != "[NEXT]") or (("[PREV]" in command.strip()) and command.strip()[-6:] != "[PREV]") ):
+-					error_dialog = gtk.MessageDialog(self.actions_dialog, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _('[PREV] and [NEXT] are only valid alone or at the end of the command'))
++					error_dialog = gtk.MessageDialog(parent=self.actions_dialog, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.CLOSE, text=_('[PREV] and [NEXT] are only valid alone or at the end of the command'))
+ 					error_dialog.set_title(_("Invalid Custom Action"))
+ 					error_dialog.run()
+ 					error_dialog.destroy()
+@@ -2143,14 +2199,15 @@ class Base:
+ 					gtk.main_iteration()
+ 				# Keep item in visible rect:
+ 				visible_rect = treeview.get_visible_rect()
+-				row_rect = treeview.get_background_area(rownum, self.tvcolumn1)
++				#row_rect = treeview.get_background_area(rownum, self.tvcolumn1)
++				row_rect = self.tree_view_get_background_area(treeview, rownum, self.tvcolumn1)
+ 				if row_rect.y + row_rect.height > visible_rect.height:
+ 					top_coord = (row_rect.y + row_rect.height - visible_rect.height) + visible_rect.y
+ 					treeview.scroll_to_point(-1, top_coord)
+ 				elif row_rect.y < 0:
+ 					treeview.scroll_to_cell(rownum)
+ 			else:
+-				error_dialog = gtk.MessageDialog(self.actions_dialog, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _('Incomplete custom action specified.'))
++				error_dialog = gtk.MessageDialog(parent=self.actions_dialog, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.CLOSE, text=_('Incomplete custom action specified.'))
+ 				error_dialog.set_title(_("Invalid Custom Action"))
+ 				error_dialog.run()
+ 				error_dialog.destroy()
+@@ -2185,7 +2242,8 @@ class Base:
+ 				# Keep item in visible rect:
+ 				rownum = rownum + 1
+ 				visible_rect = treeview.get_visible_rect()
+-				row_rect = treeview.get_background_area(rownum, self.tvcolumn1)
++				#row_rect = treeview.get_background_area(rownum, self.tvcolumn1)
++				row_rect = self.tree_view_get_background_area(treeview, rownum, self.tvcolumn1)
+ 				if row_rect.y + row_rect.height > visible_rect.height:
+ 					top_coord = (row_rect.y + row_rect.height - visible_rect.height) + visible_rect.y
+ 					treeview.scroll_to_point(-1, top_coord)
+@@ -2220,7 +2278,8 @@ class Base:
+ 				# Keep item in visible rect:
+ 				rownum = rownum - 1
+ 				visible_rect = treeview.get_visible_rect()
+-				row_rect = treeview.get_background_area(rownum, self.tvcolumn1)
++				#row_rect = treeview.get_background_area(rownum, self.tvcolumn1)
++				row_rect = self.tree_view_get_background_area(treeview, rownum, self.tvcolumn1)
+ 				if row_rect.y + row_rect.height > visible_rect.height:
+ 					top_coord = (row_rect.y + row_rect.height - visible_rect.height) + visible_rect.y
+ 					treeview.scroll_to_point(-1, top_coord)
+@@ -2228,8 +2287,9 @@ class Base:
+ 					treeview.scroll_to_cell(rownum)
+ 
+ 	def shortcut_clicked(self, widget):
+-		self.dialog_shortcut = gtk.Dialog(_("Action Shortcut"), self.dialog_name, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+-		self.shortcut_label = gtk.Label(_("Press the desired shortcut for the action."))
++		self.dialog_shortcut = gtk.Dialog(title=_("Action Shortcut"), parent=self.dialog_name, modal=True)
++		self.dialog_shortcut.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.REJECT)
++		self.shortcut_label = gtk.Label(label=_("Press the desired shortcut for the action."))
+ 		hbox = gtk.HBox()
+ 		hbox.pack_start(self.shortcut_label, False, False, 15)
+ 		self.dialog_shortcut.vbox.pack_start(hbox, False, False, 5)
+@@ -2246,14 +2306,14 @@ class Base:
+ 			# Validate to make sure the shortcut hasn't already been used:
+ 			for i in range(len(self.keys)):
+ 				if shortcut == self.keys[i][1]:
+-					error_dialog = gtk.MessageDialog(self.dialog_shortcut, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _('The shortcut \'%(shortcut)s\' is already used for \'%(key)s\'.') % {'shortcut': shortcut, 'key': self.keys[i][0]})
++					error_dialog = gtk.MessageDialog(parent=self.dialog_shortcut, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.CLOSE, text=_('The shortcut \'%(shortcut)s\' is already used for \'%(key)s\'.') % {'shortcut': shortcut, 'key': self.keys[i][0]})
+ 					error_dialog.set_title(_("Invalid Shortcut"))
+ 					error_dialog.run()
+ 					error_dialog.destroy()
+ 					return
+ 			for i in range(len(self.action_shortcuts)):
+ 				if shortcut == self.action_shortcuts[i]:
+-					error_dialog = gtk.MessageDialog(self.dialog_shortcut, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _('The shortcut \'%(shortcut)s\' is already used for \'%(key)s\'.') % {'shortcut': shortcut, 'key': self.action_names[i]})
++					error_dialog = gtk.MessageDialog(parent=self.dialog_shortcut, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.CLOSE, text=_('The shortcut \'%(shortcut)s\' is already used for \'%(key)s\'.') % {'shortcut': shortcut, 'key': self.action_names[i]})
+ 					error_dialog.set_title(_("Invalid Shortcut"))
+ 					error_dialog.run()
+ 					error_dialog.destroy()
+@@ -2283,9 +2343,9 @@ class Base:
+ 		self.tvcolumn0.clear()
+ 		self.tvcolumn1.clear()
+ 		self.tvcolumn2.clear()
+-		self.tvcolumn0.pack_start(self.cellbool)
+-		self.tvcolumn1.pack_start(self.cell)
+-		self.tvcolumn2.pack_start(self.cell)
++		self.tvcolumn0.pack_start(self.cellbool, True)
++		self.tvcolumn1.pack_start(self.cell, True)
++		self.tvcolumn2.pack_start(self.cell, True)
+ 		self.tvcolumn0.add_attribute(self.cellbool, "stock-id", 0)
+ 		self.tvcolumn1.set_attributes(self.cell, markup=1)
+ 		self.tvcolumn2.set_attributes(self.cell, text=2)
+@@ -2296,10 +2356,11 @@ class Base:
+ 		if cancel:
+ 			return
+ 		# Dialog:
+-		dialog = gtk.Dialog(_("Screenshot"), self.window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+-		snapbutton = dialog.add_button(_("_Snap"), gtk.RESPONSE_ACCEPT)
++		dialog = gtk.Dialog(title=_("Screenshot"), parent=self.window, modal=True)
++		dialog.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.REJECT)
++		snapbutton = dialog.add_button(_("_Snap"), gtk.ResponseType.ACCEPT)
+ 		snapimage = gtk.Image()
+-		snapimage.set_from_stock(gtk.STOCK_OK, gtk.ICON_SIZE_BUTTON)
++		snapimage.set_from_stock(gtk.STOCK_OK, gtk.IconSize.BUTTON)
+ 		snapbutton.set_image(snapimage)
+ 		loc = gtk.Label()
+ 		loc.set_markup('<b>' + _('Location') + '</b>')
+@@ -2314,57 +2375,58 @@ class Base:
+ 		de.set_markup('<b>' + _("Delay") + '</b>')
+ 		de.set_alignment(0, 0)
+ 		delaybox = gtk.HBox()
+-		adj = gtk.Adjustment(self.screenshot_delay, 0, 30, 1, 10, 0)
+-		delay = gtk.SpinButton(adj, 0, 0)
++		adj = gtk.Adjustment(value=self.screenshot_delay, lower=0, upper=30, step_increment=1, page_increment=10, page_size=0)
++		delay = gtk.SpinButton(adjustment = adj, climb_rate =  0, digits =  0)
+ 		delay.set_numeric(True)
+-		delay.set_update_policy(gtk.UPDATE_IF_VALID)
++		delay.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		delay.set_wrap(False)
+-		delaylabel = gtk.Label(_(" seconds"))
+-		delaybox.pack_start(delay, False)
+-		delaybox.pack_start(delaylabel, False)
++		delaylabel = gtk.Label(label=_(" seconds"))
++		delaybox.pack_start(delay, False, True, 0)
++		delaybox.pack_start(delaylabel, False, True, 0)
+ 		table = gtk.Table()
+-		table.attach(gtk.Label(), 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table.attach(loc, 1, 2, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table.attach(gtk.Label(), 1, 2, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table.attach(area1, 1, 2, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table.attach(area2, 1, 2, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table.attach(gtk.Label(), 1, 2, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table.attach(de, 1, 2, 7, 8,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table.attach(gtk.Label(), 1, 2, 8, 9,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table.attach(delaybox, 1, 2, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table.attach(gtk.Label(), 1, 2, 10, 11,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		dialog.vbox.pack_start(table)
+-		dialog.set_default_response(gtk.RESPONSE_ACCEPT)
++		table.attach(gtk.Label(), 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table.attach(loc, 1, 2, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table.attach(gtk.Label(), 1, 2, 3, 4, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table.attach(area1, 1, 2, 4, 5, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table.attach(area2, 1, 2, 5, 6, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table.attach(gtk.Label(), 1, 2, 6, 7, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table.attach(de, 1, 2, 7, 8,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table.attach(gtk.Label(), 1, 2, 8, 9,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table.attach(delaybox, 1, 2, 9, 10, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table.attach(gtk.Label(), 1, 2, 10, 11,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		dialog.vbox.pack_start(table, True, True, 0)
++		dialog.set_default_response(gtk.ResponseType.ACCEPT)
+ 		dialog.vbox.show_all()
+ 		response = dialog.run()
+-		if response == gtk.RESPONSE_ACCEPT:
++		if response == gtk.ResponseType.ACCEPT:
+ 			dialog.destroy()
+ 			while gtk.events_pending():
+ 				gtk.main_iteration()
+ 			self.screenshot_delay = delay.get_value_as_int()
+-			gobject.timeout_add(int(self.screenshot_delay*1000), self._screenshot_grab, area1.get_active())
++			GLib.timeout_add(int(self.screenshot_delay*1000), self._screenshot_grab, area1.get_active())
+ 		else:
+ 			dialog.destroy()
+ 	
+ 	def _screenshot_grab(self, entire_screen):
+-		root_win = gtk.gdk.get_default_root_window()
++		root_win = gdk.get_default_root_window()
+ 		if entire_screen:
+ 			x = 0
+ 			y = 0
+-			width = gtk.gdk.screen_width()
+-			height = gtk.gdk.screen_height()
++			width = root_win.get_screen().get_width()
++			height = root_win.get_screen().get_height()
+ 		else:
+ 			(x, y, width, height) = xmouse.geometry()
+-		pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width, height)
+-		pix = pix.get_from_drawable(root_win, gtk.gdk.colormap_get_system(), x, y, 0, 0, width, height)
++		#pix = GdkPixbuf.Pixbuf.new(colorspace=GdkPixbuf.Colorspace.RGB, has_alpha=True, bits_per_sample=8, width=width, height=height)
++		#pix = pix.get_from_drawable(root_win, gtk.gdk.colormap_get_system(), x, y, 0, 0, width, height)
+ 		# Save as /tmp/mirage-<random>/filename.ext
++		pix = gdk.pixbuf_get_from_window(root_win, x, y, width, height)
+ 		tmpdir = tempfile.mkdtemp(prefix="mirage-") + "/"
+ 		tmpfile = tmpdir + "screenshot.png"
+-		pix.save(tmpfile, 'png')
++		pix.savev(filename=tmpfile, type='png', option_keys=[None], option_values=[None])
+ 		# Load file:
+ 		self.image_list = [tmpfile]
+ 		self.curr_img_in_list = 0
+-		gobject.idle_add(self.load_new_image2, False, False, False, False, True)
++		GLib.idle_add(self.load_new_image2, False, False, False, False, True)
+ 		self.update_statusbar()
+ 		self.set_go_navigation_sensitivities(False)
+ 		self.set_slideshow_sensitivities()
+@@ -2373,12 +2435,12 @@ class Base:
+ 		self.window.present()
+ 
+ 	def show_properties(self, action):
+-		show_props = gtk.Dialog(_("Properties"), self.window)
+-		show_props.set_has_separator(False)
++		show_props = gtk.Dialog(title=_("Properties"), parent=self.window)
++		#show_props.set_has_separator(False)
+ 		show_props.set_resizable(False)
+-		table = gtk.Table(3, 3, False)
++		table = gtk.Table(n_rows=3, n_columns=3, homogeneous=False)
+ 		image = gtk.Image()
+-		animtest = gtk.gdk.PixbufAnimation(self.currimg_name)
++		animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.currimg_name)
+ 		image_is_anim = False
+ 		if animtest.is_static_image():
+ 			pixbuf, image_width, image_height = self.get_pixbuf_of_size(self.currimg_pixbuf_original, 180, self.zoom_quality)
+@@ -2387,23 +2449,23 @@ class Base:
+ 			image_is_anim = True
+ 		image.set_from_pixbuf(self.pixbuf_add_border(pixbuf))
+ 		vbox_left = gtk.VBox()
+-		filename = gtk.Label(_("File name:"))
++		filename = gtk.Label(label=_("File name:"))
+ 		filename.set_alignment(1, 1)
+-		filedate = gtk.Label(_("File modified:"))
++		filedate = gtk.Label(label=_("File modified:"))
+ 		filedate.set_alignment(1, 1)
+-		imagesize = gtk.Label(_("Dimensions:"))
++		imagesize = gtk.Label(label=_("Dimensions:"))
+ 		imagesize.set_alignment(1, 1)
+-		filesize = gtk.Label(_("File size:"))
++		filesize = gtk.Label(label=_("File size:"))
+ 		filesize.set_alignment(1, 1)
+-		filetype = gtk.Label(_("File type:"))
++		filetype = gtk.Label(label=_("File type:"))
+ 		filetype.set_alignment(1, 1)
+-		transparency = gtk.Label(_("Transparency:"))
++		transparency = gtk.Label(label=_("Transparency:"))
+ 		transparency.set_alignment(1, 1)
+-		animation = gtk.Label(_("Animation:"))
++		animation = gtk.Label(label=_("Animation:"))
+ 		animation.set_alignment(1, 1)
+-		bits = gtk.Label(_("Bits per sample:"))
++		bits = gtk.Label(label=_("Bits per sample:"))
+ 		bits.set_alignment(1, 1)
+-		channels = gtk.Label(_("Channels:"))
++		channels = gtk.Label(label=_("Channels:"))
+ 		channels.set_alignment(1, 1)
+ 		vbox_left.pack_start(filename, False, False, 2)
+ 		vbox_left.pack_start(filedate, False, False, 2)
+@@ -2416,21 +2478,21 @@ class Base:
+ 		vbox_left.pack_start(channels, False, False, 2)
+ 		vbox_right = gtk.VBox()
+ 		filestat = os.stat(self.currimg_name)
+-		filename2 = gtk.Label(os.path.basename(self.currimg_name))
+-		filedate2 = gtk.Label(time.strftime('%c', time.localtime(filestat[stat.ST_MTIME])))
+-		imagesize2 = gtk.Label(str(self.currimg_pixbuf_original.get_width()) + "x" + str(self.currimg_pixbuf_original.get_height()))
+-		filetype2 = gtk.Label(gtk.gdk.pixbuf_get_file_info(self.currimg_name)[0]['mime_types'][0])
+-		filesize2 = gtk.Label(str(filestat[stat.ST_SIZE]/1000) + "KB")
++		filename2 = gtk.Label(label=os.path.basename(self.currimg_name))
++		filedate2 = gtk.Label(label=time.strftime('%c', time.localtime(filestat[stat.ST_MTIME])))
++		imagesize2 = gtk.Label(label=str(self.currimg_pixbuf_original.get_width()) + "x" + str(self.currimg_pixbuf_original.get_height()))
++		filetype2 = gtk.Label(label=GdkPixbuf.Pixbuf.get_file_info(self.currimg_name)[0].get_mime_types()[0])
++		filesize2 = gtk.Label(label=str(filestat[stat.ST_SIZE]/1000) + "KB")
+ 		if not image_is_anim and pixbuf.get_has_alpha():
+-			transparency2 = gtk.Label(_("Yes"))
++			transparency2 = gtk.Label(label=_("Yes"))
+ 		else:
+-			transparency2 = gtk.Label(_("No"))
++			transparency2 = gtk.Label(label=_("No"))
+ 		if animtest.is_static_image():
+-			animation2 = gtk.Label(_("No"))
++			animation2 = gtk.Label(label=_("No"))
+ 		else:
+-			animation2 = gtk.Label(_("Yes"))
+-		bits2 = gtk.Label(str(pixbuf.get_bits_per_sample()))
+-		channels2 = gtk.Label(str(pixbuf.get_n_channels()))
++			animation2 = gtk.Label(label=_("Yes"))
++		bits2 = gtk.Label(label=str(pixbuf.get_bits_per_sample()))
++		channels2 = gtk.Label(label=str(pixbuf.get_n_channels()))
+ 		filename2.set_alignment(0, 1)
+ 		filedate2.set_alignment(0, 1)
+ 		imagesize2.set_alignment(0, 1)
+@@ -2452,28 +2514,30 @@ class Base:
+ 		hbox = gtk.HBox()
+ 		hbox.pack_start(vbox_left, False, False, 3)
+ 		hbox.pack_start(vbox_right, False, False, 3)
+-		table.attach(image, 1, 2, 1, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table.attach(hbox, 2, 3, 1, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
++		table.attach(image, 1, 2, 1, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table.attach(hbox, 2, 3, 1, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
+ 		show_props.vbox.pack_start(table, False, False, 15)
+ 		show_props.vbox.show_all()
+-		close_button = show_props.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
++		close_button = show_props.add_button(gtk.STOCK_CLOSE, gtk.ResponseType.CLOSE)
+ 		close_button.grab_focus()
+ 		show_props.run()
+ 		show_props.destroy()
+ 
+ 	def show_prefs(self, action):
+ 		prev_thumbnail_size = self.thumbnail_size
+-		self.prefs_dialog = gtk.Dialog(_("Mirage Preferences"), self.window)
+-		self.prefs_dialog.set_has_separator(False)
++		self.prefs_dialog = gtk.Dialog(title=_("Mirage Preferences"), parent=self.window)
++		#self.prefs_dialog.set_has_separator(False)
+ 		self.prefs_dialog.set_resizable(False)
+ 		# "Interface" prefs:
+-		table_settings = gtk.Table(14, 3, False)
++		table_settings = gtk.Table(n_rows=14, n_columns=3, homogeneous=False)
+ 		bglabel = gtk.Label()
+ 		bglabel.set_markup('<b>' + _('Interface') + '</b>')
+ 		bglabel.set_alignment(0, 1)
+-		color_hbox = gtk.HBox(False, 0)
+-		colortext = gtk.Label(_('Background color:'))
+-		self.colorbutton = gtk.ColorButton(self.bgcolor)
++		color_hbox = gtk.HBox(homogeneous=False, spacing=0)
++		colortext = gtk.Label(label=_('Background color:'))
++		#self.colorbutton = gtk.ColorButton(label=self.bgcolor)
++		bg_rgba = gdk.RGBA.from_color(self.bgcolor)
++		self.colorbutton = gtk.ColorButton.new_with_rgba(bg_rgba)
+ 		self.colorbutton.connect('color-set', self.bgcolor_selected)
+ 		self.colorbutton.set_size_request(150, -1)
+ 		self.colorbutton.set_tooltip_text(_("Sets the background color for the application."))
+@@ -2481,8 +2545,8 @@ class Base:
+ 		color_hbox.pack_start(self.colorbutton, False, False, 0)
+ 		color_hbox.pack_start(gtk.Label(), True, True, 0)
+ 		
+-		simplecolor_hbox = gtk.HBox(False, 0)
+-		simplecolortext = gtk.Label(_('Simple background color:'))
++		simplecolor_hbox = gtk.HBox(homogeneous=False, spacing=0)
++		simplecolortext = gtk.Label(label=_('Simple background color:'))
+ 		simplecolorbutton = gtk.CheckButton()
+ 		simplecolorbutton.connect('toggled', self.simple_bgcolor_selected)
+ 		simplecolor_hbox.pack_start(simplecolortext, False, False, 0)
+@@ -2491,12 +2555,12 @@ class Base:
+ 		if self.simple_bgcolor:
+ 				simplecolorbutton.set_active(True)
+ 		
+-		fullscreen = gtk.CheckButton(_("Open Mirage in fullscreen mode"))
++		fullscreen = gtk.CheckButton(label=_("Open Mirage in fullscreen mode"))
+ 		fullscreen.set_active(self.start_in_fullscreen)
+ 		thumbbox = gtk.HBox()
+-		thumblabel = gtk.Label(_("Thumbnail size:"))
++		thumblabel = gtk.Label(label=_("Thumbnail size:"))
+ 		thumbbox.pack_start(thumblabel, False, False, 0)
+-		thumbsize = gtk.combo_box_new_text()
++		thumbsize = gtk.ComboBoxText.new()
+ 		option = 0
+ 		for size in self.thumbnail_sizes:
+ 			thumbsize.append_text(size + " x " + size)
+@@ -2504,38 +2568,38 @@ class Base:
+ 				thumbsize.set_active(option)
+ 			option += 1
+ 		thumbbox.pack_start(thumbsize, False, False, 5)
+-		table_settings.attach(gtk.Label(), 1, 3, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_settings.attach(bglabel, 1, 3, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_settings.attach(simplecolor_hbox, 1, 2, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(color_hbox, 1, 2, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_settings.attach(thumbbox, 1, 3, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 8, 9,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(fullscreen, 1, 3, 9, 10,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 11, 12,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 12, 13,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 13, 14,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_settings.attach(gtk.Label(), 1, 3, 14, 15,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_settings.attach(bglabel, 1, 3, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 3, 4, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_settings.attach(simplecolor_hbox, 1, 2, 4, 5, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(color_hbox, 1, 2, 5, 6, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 6, 7, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_settings.attach(thumbbox, 1, 3, 7, 8, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 8, 9,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(fullscreen, 1, 3, 9, 10,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 10, 11, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 11, 12,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 12, 13,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 13, 14,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_settings.attach(gtk.Label(), 1, 3, 14, 15,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
+ 		# "Behavior" tab:
+-		table_behavior = gtk.Table(14, 2, False)
++		table_behavior = gtk.Table(n_rows=14, n_columns=2, homogeneous=False)
+ 		openlabel = gtk.Label()
+ 		openlabel.set_markup('<b>' + _('Open Behavior') + '</b>')
+ 		openlabel.set_alignment(0, 1)
+ 		hbox_openmode = gtk.HBox()
+-		hbox_openmode.pack_start(gtk.Label(_('Open new image in:')), False, False, 0)
+-		combobox = gtk.combo_box_new_text()
++		hbox_openmode.pack_start(gtk.Label(label=_('Open new image in:')), False, False, 0)
++		combobox = gtk.ComboBoxText.new()
+ 		combobox.append_text(_("Smart Mode"))
+ 		combobox.append_text(_("Zoom To Fit Mode"))
+ 		combobox.append_text(_("1:1 Mode"))
+ 		combobox.append_text(_("Last Active Mode"))
+ 		combobox.set_active(self.open_mode)
+ 		hbox_openmode.pack_start(combobox, False, False, 5)
+-		openallimages = gtk.CheckButton(_("Load all images in current directory"))
++		openallimages = gtk.CheckButton(label=_("Load all images in current directory"))
+ 		openallimages.set_active(self.open_all_images)
+ 		openallimages.set_tooltip_text(_("If enabled, opening an image in Mirage will automatically load all images found in that image's directory."))
+-		hiddenimages = gtk.CheckButton(_("Allow loading hidden files"))
++		hiddenimages = gtk.CheckButton(label=_("Allow loading hidden files"))
+ 		hiddenimages.set_active(self.open_hidden_files)
+ 		hiddenimages.set_tooltip_text(_("If checked, Mirage will open hidden files. Otherwise, hidden files will be ignored."))
+ 		openpref = gtk.RadioButton()
+@@ -2561,20 +2625,20 @@ class Base:
+ 		else:
+ 			openpref2.set_active(True)
+ 			self.defaultdir.set_sensitive(True)
+-		table_behavior.attach(gtk.Label(), 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_behavior.attach(openlabel, 1, 2, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_behavior.attach(gtk.Label(), 1, 2, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_behavior.attach(hbox_openmode, 1, 2, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_behavior.attach(gtk.Label(), 1, 2, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_behavior.attach(openallimages, 1, 2, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_behavior.attach(hiddenimages, 1, 2, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_behavior.attach(gtk.Label(), 1, 2, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_behavior.attach(openpref1, 1, 2, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_behavior.attach(openpref2, 1, 2, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_behavior.attach(hbox_defaultdir, 1, 2, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 45, 0)
+-		table_behavior.attach(gtk.Label(), 1, 2, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 45, 0)
++		table_behavior.attach(gtk.Label(), 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_behavior.attach(openlabel, 1, 2, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_behavior.attach(gtk.Label(), 1, 2, 3, 4, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_behavior.attach(hbox_openmode, 1, 2, 4, 5, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_behavior.attach(gtk.Label(), 1, 2, 5, 6, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_behavior.attach(openallimages, 1, 2, 6, 7, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_behavior.attach(hiddenimages, 1, 2, 7, 8, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_behavior.attach(gtk.Label(), 1, 2, 8, 9, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_behavior.attach(openpref1, 1, 2, 9, 10, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_behavior.attach(openpref2, 1, 2, 10, 11, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_behavior.attach(hbox_defaultdir, 1, 2, 11, 12, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 45, 0)
++		table_behavior.attach(gtk.Label(), 1, 2, 12, 13, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 45, 0)
+ 		# "Navigation" tab:
+-		table_navigation = gtk.Table(14, 2, False)
++		table_navigation = gtk.Table(n_rows=14, n_columns=2, homogeneous=False)
+ 		navlabel = gtk.Label()
+ 		navlabel.set_markup('<b>' + _('Navigation') + '</b>')
+ 		navlabel.set_alignment(0, 1)
+@@ -2582,70 +2646,70 @@ class Base:
+ 		preloadnav.set_active(self.preloading_images)
+ 		preloadnav.set_tooltip_text(_("If enabled, the next and previous images in the list will be preloaded during idle time. Note that the speed increase comes at the expense of memory usage, so it is recommended to disable this option on machines with limited ram."))
+ 		hbox_listwrap = gtk.HBox()
+-		hbox_listwrap.pack_start(gtk.Label(_("Wrap around imagelist:")), False, False, 0)
+-		combobox2 = gtk.combo_box_new_text()
++		hbox_listwrap.pack_start(gtk.Label(label=_("Wrap around imagelist:")), False, False, 0)
++		combobox2 = gtk.ComboBoxText.new()
+ 		combobox2.append_text(_("No"))
+ 		combobox2.append_text(_("Yes"))
+ 		combobox2.append_text(_("Prompt User"))
+ 		combobox2.set_active(self.listwrap_mode)
+ 		hbox_listwrap.pack_start(combobox2, False, False, 5)
+-		table_navigation.attach(gtk.Label(), 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_navigation.attach(navlabel, 1, 2, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_navigation.attach(hbox_listwrap, 1, 2, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_navigation.attach(preloadnav, 1, 2, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_navigation.attach(gtk.Label(), 1, 2, 13, 14, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_navigation.attach(navlabel, 1, 2, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 3, 4, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_navigation.attach(hbox_listwrap, 1, 2, 4, 5, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 5, 6, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_navigation.attach(preloadnav, 1, 2, 6, 7, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 7, 8, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 8, 9, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 9, 10, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 10, 11, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 11, 12, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 12, 13, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_navigation.attach(gtk.Label(), 1, 2, 13, 14, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
+ 		# "Slideshow" tab:
+-		table_slideshow = gtk.Table(14, 2, False)
++		table_slideshow = gtk.Table(n_rows=14, n_columns=2, homogeneous=False)
+ 		slideshowlabel = gtk.Label()
+ 		slideshowlabel.set_markup('<b>' + _('Slideshow Mode') + '</b>')
+ 		slideshowlabel.set_alignment(0, 1)
+ 		hbox_delay = gtk.HBox()
+-		hbox_delay.pack_start(gtk.Label(_("Delay between images in seconds:")), False, False, 0)
+-		spin_adj = gtk.Adjustment(self.slideshow_delay, 0, 50000, 1, 10, 0)
+-		delayspin = gtk.SpinButton(spin_adj, 1.0, 0)
++		hbox_delay.pack_start(gtk.Label(label=_("Delay between images in seconds:")), False, False, 0)
++		spin_adj = gtk.Adjustment(value=self.slideshow_delay, lower=0, upper=50000, step_increment=1, page_increment=10, page_size=0)
++		delayspin = gtk.SpinButton(adjustment = spin_adj, climb_rate = 1.0, digits = 0)
+ 		delayspin.set_numeric(True)
+ 		hbox_delay.pack_start(delayspin, False, False, 5)
+-		randomize = gtk.CheckButton(_("Randomize order of images"))
++		randomize = gtk.CheckButton(label=_("Randomize order of images"))
+ 		randomize.set_active(self.slideshow_random)
+ 		randomize.set_tooltip_text(_("If enabled, a random image will be chosen during slideshow mode (without loading any image twice)."))
+-		disable_screensaver = gtk.CheckButton(_("Disable screensaver in slideshow mode"))
++		disable_screensaver = gtk.CheckButton(label=_("Disable screensaver in slideshow mode"))
+ 		disable_screensaver.set_active(self.disable_screensaver)
+ 		disable_screensaver.set_tooltip_text(_("If enabled, xscreensaver will be temporarily disabled during slideshow mode."))
+-		ss_in_fs = gtk.CheckButton(_("Always start in fullscreen mode"))
++		ss_in_fs = gtk.CheckButton(label=_("Always start in fullscreen mode"))
+ 		ss_in_fs.set_tooltip_text(_("If enabled, starting a slideshow will put the application in fullscreen mode."))
+ 		ss_in_fs.set_active(self.slideshow_in_fullscreen)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 1, 2, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(slideshowlabel, 1, 2, 2, 3, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 3, 4, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(hbox_delay, 1, 2, 4, 5, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 5, 6, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(disable_screensaver, 1, 2, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_slideshow.attach(ss_in_fs, 1, 2, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_slideshow.attach(randomize, 1, 2, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 9, 10, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 10, 11, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 11, 12, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 12, 13, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
+-		table_slideshow.attach(gtk.Label(), 1, 2, 13, 14, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 0, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 1, 2, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(slideshowlabel, 1, 2, 2, 3, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 3, 4, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(hbox_delay, 1, 2, 4, 5, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 5, 6, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(disable_screensaver, 1, 2, 6, 7, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_slideshow.attach(ss_in_fs, 1, 2, 7, 8, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_slideshow.attach(randomize, 1, 2, 8, 9, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 9, 10, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 10, 11, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 11, 12, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 12, 13, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
++		table_slideshow.attach(gtk.Label(), 1, 2, 13, 14, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 0, 0)
+ 		# "Image" tab:
+-		table_image = gtk.Table(14, 2, False)
++		table_image = gtk.Table(n_rows=14, n_columns=2, homogeneous=False)
+ 		imagelabel = gtk.Label()
+ 		imagelabel.set_markup('<b>' + _('Image Editing') + '</b>')
+ 		imagelabel.set_alignment(0, 1)
+-		deletebutton = gtk.CheckButton(_("Confirm image delete"))
++		deletebutton = gtk.CheckButton(label=_("Confirm image delete"))
+ 		deletebutton.set_active(self.confirm_delete)
+ 		
+ 		zoom_hbox = gtk.HBox()
+-		zoom_hbox.pack_start(gtk.Label(_('Scaling quality:')), False, False, 0)
+-		zoomcombo = gtk.combo_box_new_text()
++		zoom_hbox.pack_start(gtk.Label(label=_('Scaling quality:')), False, False, 0)
++		zoomcombo = gtk.ComboBoxText.new()
+ 		zoomcombo.append_text(_("Nearest (Fastest)"))
+ 		zoomcombo.append_text(_("Tiles"))
+ 		zoomcombo.append_text(_("Bilinear"))
+@@ -2655,8 +2719,8 @@ class Base:
+ 		zoom_hbox.pack_start(gtk.Label(), True, True, 0)
+ 		
+ 		hbox_save = gtk.HBox()
+-		savelabel = gtk.Label(_("Modified images:"))
+-		savecombo = gtk.combo_box_new_text()
++		savelabel = gtk.Label(label=_("Modified images:"))
++		savecombo = gtk.ComboBoxText.new()
+ 		savecombo.append_text(_("Ignore Changes"))
+ 		savecombo.append_text(_("Auto-Save"))
+ 		savecombo.append_text(_("Prompt For Action"))
+@@ -2665,33 +2729,33 @@ class Base:
+ 		hbox_save.pack_start(savecombo, False, False, 5)
+ 		
+ 		hbox_quality = gtk.HBox()
+-		qualitylabel = gtk.Label(_("Quality to save in:"))
+-		qspin_adj = gtk.Adjustment(self.quality_save, 0, 100, 1, 100, 0)
+-		qualityspin = gtk.SpinButton(qspin_adj, 1.0, 0)
++		qualitylabel = gtk.Label(label=_("Quality to save in:"))
++		qspin_adj = gtk.Adjustment(value=self.quality_save, lower=0, upper=100, step_increment=1, page_increment=100, page_size=0)
++		qualityspin = gtk.SpinButton(adjustment = qspin_adj, climb_rate =  1.0, digits =  0)
+ 		qualityspin.set_numeric(True)
+ 		hbox_quality.pack_start(qualitylabel, False, False, 0)
+ 		hbox_quality.pack_start(qualityspin, False, False, 5)
+-		table_image.attach(gtk.Label(), 1, 3, 1, 2,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(imagelabel, 1, 3, 2, 3,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 15, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 3, 4,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(zoom_hbox, 1, 3, 4, 5,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 5, 6,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(hbox_save, 1, 3, 6, 7, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 7, 8, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(hbox_quality, 1, 3, 8, 9, gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 9, 10,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(deletebutton, 1, 3, 10, 11,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 11, 12,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 12, 13,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 13, 14,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
+-		table_image.attach(gtk.Label(), 1, 3, 14, 15,  gtk.FILL|gtk.EXPAND, gtk.FILL|gtk.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 1, 2,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(imagelabel, 1, 3, 2, 3,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 15, 0)
++		table_image.attach(gtk.Label(), 1, 3, 3, 4,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(zoom_hbox, 1, 3, 4, 5,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 5, 6,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(hbox_save, 1, 3, 6, 7, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 7, 8, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(hbox_quality, 1, 3, 8, 9, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 9, 10,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(deletebutton, 1, 3, 10, 11,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 11, 12,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 12, 13,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 13, 14,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
++		table_image.attach(gtk.Label(), 1, 3, 14, 15,  gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, gtk.AttachOptions.FILL|gtk.AttachOptions.EXPAND, 30, 0)
+ 		# Add tabs:
+ 		notebook = gtk.Notebook()
+-		notebook.append_page(table_behavior, gtk.Label(_("Behavior")))
+-		notebook.append_page(table_navigation, gtk.Label(_("Navigation")))
+-		notebook.append_page(table_settings, gtk.Label(_("Interface")))
+-		notebook.append_page(table_slideshow, gtk.Label(_("Slideshow")))
+-		notebook.append_page(table_image, gtk.Label(_("Image")))
++		notebook.append_page(table_behavior, gtk.Label(label=_("Behavior")))
++		notebook.append_page(table_navigation, gtk.Label(label=_("Navigation")))
++		notebook.append_page(table_settings, gtk.Label(label=_("Interface")))
++		notebook.append_page(table_slideshow, gtk.Label(label=_("Slideshow")))
++		notebook.append_page(table_image, gtk.Label(label=_("Image")))
+ 		notebook.set_current_page(0)
+ 		hbox = gtk.HBox()
+ 		self.prefs_dialog.vbox.pack_start(hbox, False, False, 7)
+@@ -2699,19 +2763,19 @@ class Base:
+ 		notebook.connect('switch-page', self.prefs_tab_switched)
+ 		# Show prefs:
+ 		self.prefs_dialog.vbox.show_all()
+-		self.close_button = self.prefs_dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
++		self.close_button = self.prefs_dialog.add_button(gtk.STOCK_CLOSE, gtk.ResponseType.CLOSE)
+ 		self.close_button.grab_focus()
+ 		response = self.prefs_dialog.run()
+-		if response == gtk.RESPONSE_CLOSE or response == gtk.RESPONSE_DELETE_EVENT:
++		if response == gtk.ResponseType.CLOSE or response == gtk.ResponseType.DELETE_EVENT:
+ 			self.zoomvalue = zoomcombo.get_active()
+ 			if int(round(self.zoomvalue, 0)) == 0:
+-				self.zoom_quality = gtk.gdk.INTERP_NEAREST
++				self.zoom_quality = GdkPixbuf.InterpType.NEAREST
+ 			elif int(round(self.zoomvalue, 0)) == 1:
+-				self.zoom_quality = gtk.gdk.INTERP_TILES
++				self.zoom_quality = GdkPixbuf.InterpType.TILES
+ 			elif int(round(self.zoomvalue, 0)) == 2:
+-				self.zoom_quality = gtk.gdk.INTERP_BILINEAR
++				self.zoom_quality = GdkPixbuf.InterpType.BILINEAR
+ 			elif int(round(self.zoomvalue, 0)) == 3:
+-				self.zoom_quality = gtk.gdk.INTERP_HYPER
++				self.zoom_quality = GdkPixbuf.InterpType.HYPER
+ 			self.open_all_images = openallimages.get_active()
+ 			self.open_hidden_files = hiddenimages.get_active()
+ 			if openpref1.get_active():
+@@ -2735,16 +2799,16 @@ class Base:
+ 			self.quality_save = qualityspin.get_value()
+ 			self.thumbnail_size = int(self.thumbnail_sizes[thumbsize.get_active()])
+ 			if self.thumbnail_size != prev_thumbnail_size:
+-				gobject.idle_add(self.thumbpane_set_size)
+-				gobject.idle_add(self.thumbpane_update_images, True, self.curr_img_in_list)
++				GLib.idle_add(self.thumbpane_set_size)
++				GLib.idle_add(self.thumbpane_update_images, True, self.curr_img_in_list)
+ 			self.prefs_dialog.destroy()
+ 			self.set_go_navigation_sensitivities(False)
+ 			if (self.preloading_images and not preloading_images_prev) or (open_mode_prev != self.open_mode):
+ 				# The user just turned on preloading, so do it:
+ 				self.preloadimg_next_in_list = -1
+ 				self.preloadimg_prev_in_list = -1
+-				self.preload_when_idle = gobject.idle_add(self.preload_next_image, False)
+-				self.preload_when_idle2 = gobject.idle_add(self.preload_prev_image, False)
++				self.preload_when_idle = GLib.idle_add(self.preload_next_image, False)
++				self.preload_when_idle2 = GLib.idle_add(self.preload_prev_image, False)
+ 			elif not self.preloading_images:
+ 				self.preloadimg_next_in_list = -1
+ 				self.preloadimg_prev_in_list = -1
+@@ -2760,24 +2824,24 @@ class Base:
+ 			temp_slideshow_mode = self.slideshow_mode
+ 			if self.slideshow_mode:
+ 				self.toggle_slideshow(None)
+-			rename_dialog = gtk.Dialog(_('Rename Image'), self.window, gtk.DIALOG_MODAL)
++			rename_dialog = gtk.Dialog(title=_('Rename Image'), parent=self.window, modal=True)
+ 			self.rename_txt = gtk.Entry()
+ 			filename = os.path.basename(self.currimg_name)
+ 			self.rename_txt.set_text(filename)
+ 			self.rename_txt.set_activates_default(True)
+-			cancelbutton = rename_dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+-			renamebutton = rename_dialog.add_button(_("_Rename"), gtk.RESPONSE_ACCEPT)
++			cancelbutton = rename_dialog.add_button(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL)
++			renamebutton = rename_dialog.add_button(_("_Rename"), gtk.ResponseType.ACCEPT)
+ 			renameimage = gtk.Image()
+-			renameimage.set_from_stock(gtk.STOCK_OK, gtk.ICON_SIZE_BUTTON)
++			renameimage.set_from_stock(gtk.STOCK_OK, gtk.IconSize.BUTTON)
+ 			renamebutton.set_image(renameimage)
+-			animtest = gtk.gdk.PixbufAnimation(self.currimg_name)
++			animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.currimg_name)
+ 			if animtest.is_static_image():
+ 				pixbuf, image_width, image_height = self.get_pixbuf_of_size(self.currimg_pixbuf_original, 60, self.zoom_quality)
+ 			else:
+ 				pixbuf, image_width, image_height = self.get_pixbuf_of_size(animtest.get_static_image(), 60, self.zoom_quality)
+ 			image = gtk.Image()
+ 			image.set_from_pixbuf(pixbuf)
+-			instructions = gtk.Label(_("Enter the new name:"))
++			instructions = gtk.Label(label=_("Enter the new name:"))
+ 			instructions.set_alignment(0, 1)
+ 			hbox = gtk.HBox()
+ 			hbox.pack_start(image, False, False, 10)
+@@ -2789,13 +2853,13 @@ class Base:
+ 			vbox_stuff.pack_start(gtk.Label(), False, False, 0)
+ 			hbox.pack_start(vbox_stuff, True, True, 10)
+ 			rename_dialog.vbox.pack_start(hbox, False, False, 0)
+-			rename_dialog.set_has_separator(True)
+-			rename_dialog.set_default_response(gtk.RESPONSE_ACCEPT)
++			#rename_dialog.set_has_separator(True)
++			rename_dialog.set_default_response(gtk.ResponseType.ACCEPT)
+ 			rename_dialog.set_size_request(300, -1)
+ 			rename_dialog.vbox.show_all()
+ 			rename_dialog.connect('show', self.select_rename_text)
+ 			response = rename_dialog.run()
+-			if response == gtk.RESPONSE_ACCEPT:
++			if response == gtk.ResponseType.ACCEPT:
+ 				try:
+ 					new_filename = os.path.dirname(self.currimg_name) + "/" + self.rename_txt.get_text()
+ 					shutil.move(self.currimg_name, new_filename)
+@@ -2809,7 +2873,7 @@ class Base:
+ 					self.register_file_with_recent_docs(self.currimg_name)
+ 					self.update_title()
+ 				except:
+-					error_dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _('Unable to rename %s') % self.currimg_name)
++					error_dialog = gtk.MessageDialog(parent=self.window, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.OK, text=_('Unable to rename %s') % self.currimg_name)
+ 					error_dialog.set_title(_("Unable to rename"))
+ 					error_dialog.run()
+ 					error_dialog.destroy()
+@@ -2827,28 +2891,28 @@ class Base:
+ 			temp_slideshow_mode = self.slideshow_mode
+ 			if self.slideshow_mode:
+ 				self.toggle_slideshow(None)
+-			delete_dialog = gtk.Dialog(_('Delete Image'), self.window, gtk.DIALOG_MODAL)
++			delete_dialog = gtk.Dialog(title=_('Delete Image'), parent=self.window, modal=True)
+ 			if self.confirm_delete:
+-				permlabel = gtk.Label(_('Are you sure you wish to permanently delete %s?') % os.path.split(self.currimg_name)[1])
++				permlabel = gtk.Label(label=_('Are you sure you wish to permanently delete %s?') % os.path.split(self.currimg_name)[1])
+ 				permlabel.set_line_wrap(True)
+ 				permlabel.set_alignment(0, 0.1)
+ 				warningicon = gtk.Image()
+-				warningicon.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
++				warningicon.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.IconSize.DIALOG)
+ 				hbox = gtk.HBox()
+ 				hbox.pack_start(warningicon, False, False, 10)
+ 				hbox.pack_start(permlabel, False, False, 10)
+ 				delete_dialog.vbox.pack_start(gtk.Label(), False, False, 0)
+ 				delete_dialog.vbox.pack_start(hbox, False, False, 0)
+-				cancelbutton = delete_dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+-				deletebutton = delete_dialog.add_button(gtk.STOCK_DELETE, gtk.RESPONSE_YES)
+-				delete_dialog.set_has_separator(False)
++				cancelbutton = delete_dialog.add_button(gtk.STOCK_CANCEL, gtk.ResponseType.CANCEL)
++				deletebutton = delete_dialog.add_button(gtk.STOCK_DELETE, gtk.ResponseType.YES)
++				#delete_dialog.set_has_separator(False)
+ 				deletebutton.set_property('has-focus', True)
+-				delete_dialog.set_default_response(gtk.RESPONSE_YES)
++				delete_dialog.set_default_response(gtk.ResponseType.YES)
+ 				delete_dialog.vbox.show_all()
+ 				response = delete_dialog.run()
+ 			else:
+-				response = gtk.RESPONSE_YES
+-			if response  == gtk.RESPONSE_YES:
++				response = gtk.ResponseType.YES
++			if response  == gtk.ResponseType.YES:
+ 				try:
+ 					os.remove(self.currimg_name)
+ 					self.image_modified = False
+@@ -2874,10 +2938,10 @@ class Base:
+ 							self.curr_img_in_list = 0
+ 						elif self.curr_img_in_list == len(self.image_list):
+ 							self.curr_img_in_list -= 1
+-						self.change_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
++						self.change_cursor(gdk.Cursor(gdk.CursorType.WATCH))
+ 						self.preloadimg_prev_in_list = -1
+ 						self.preloadimg_next_in_list = -1
+-						self.load_when_idle = gobject.idle_add(self.load_new_image, False, False, True, True, True, True)
++						self.load_when_idle = GLib.idle_add(self.load_new_image, False, False, True, True, True, True)
+ 						self.set_go_navigation_sensitivities(False)
+ 					else:
+ 						self.imageview.clear()
+@@ -2890,7 +2954,7 @@ class Base:
+ 					# Select new item:
+ 					self.thumbpane_select(self.curr_img_in_list)
+ 				except:
+-					error_dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, _('Unable to delete %s') % self.currimg_name)
++					error_dialog = gtk.MessageDialog(parent=self.window, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.OK, text=_('Unable to delete %s') % self.currimg_name)
+ 					error_dialog.set_title(_("Unable to delete"))
+ 					error_dialog.run()
+ 					error_dialog.destroy()
+@@ -2899,12 +2963,12 @@ class Base:
+ 				self.toggle_slideshow(None)
+ 
+ 	def defaultdir_clicked(self, button):
+-		getdir = gtk.FileChooserDialog(title=_("Choose directory"),action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+-		getdir.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
++		getdir = gtk.FileChooserDialog(title=_("Choose directory"),action=gtk.FileChooserAction.OPEN,buttons=(gtk.STOCK_CANCEL,gtk.ResponseType.CANCEL,gtk.STOCK_OPEN,gtk.ResponseType.OK))
++		getdir.set_action(gtk.FileChooserAction.SELECT_FOLDER)
+ 		getdir.set_filename(self.fixed_dir)
+-		getdir.set_default_response(gtk.RESPONSE_OK)
++		getdir.set_default_response(gtk.ResponseType.OK)
+ 		response = getdir.run()
+-		if response == gtk.RESPONSE_OK:
++		if response == gtk.ResponseType.OK:
+ 			self.fixed_dir = getdir.get_filenames()[0]
+ 			if len(self.fixed_dir) > 25:
+ 				button.set_label('...' + self.fixed_dir[-22:])
+@@ -2915,7 +2979,7 @@ class Base:
+ 			getdir.destroy()
+ 
+ 	def prefs_tab_switched(self, notebook, page, page_num):
+-		do_when_idle = gobject.idle_add(self.grab_close_button)
++		do_when_idle = GLib.idle_add(self.grab_close_button)
+ 
+ 	def grab_close_button(self):
+ 		self.close_button.grab_focus()
+@@ -2925,14 +2989,18 @@ class Base:
+ 		# later be saved to .miragerc) and set this background color:
+ 		self.bgcolor = widget.get_property('color')
+ 		if not self.simple_bgcolor:
+-			self.layout.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
+-			self.slideshow_window.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
+-			self.slideshow_window2.modify_bg(gtk.STATE_NORMAL, self.bgcolor)
++			#self.layout.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++			#self.slideshow_window.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++			#self.slideshow_window2.modify_bg(gtk.StateType.NORMAL, self.bgcolor)
++			self.modify_bg(self.layout_vbox, self.bgcolor)
++			self.modify_bg(self.slideshow_window, self.bgcolor)
++			self.modify_bg(self.slideshow_window2, self.bgcolor)
+ 
+ 	def simple_bgcolor_selected(self, widget):
+ 		if widget.get_active():
+ 			self.simple_bgcolor = True
+-			self.layout.modify_bg(gtk.STATE_NORMAL, None)
++			#self.layout.modify_bg(gtk.StateType.NORMAL, None)
++			self.modify_bg(self.layout_vbox, None)
+ 		else:
+ 			self.simple_bgcolor = False
+ 			self.bgcolor_selected(self.colorbutton)
+@@ -2952,11 +3020,13 @@ class Base:
+ 		self.about_dialog.set_authors(['Scott Horowitz <stonecrest at gmail.com>', 'Fredric Johansson <fredric.miscmail at gmail.com>'])
+ 		self.about_dialog.set_artists(['William Rea <sillywilly at gmail.com>'])
+ 		self.about_dialog.set_translator_credits('cs - Petr Pisar <petr.pisar at atlas.cz>\nde - Bjoern Martensen <bjoern.martensen at gmail.com>\nes - Isidro Arribas <cdhotfire at gmail.com>\nfr - Mike Massonnet <mmassonnet at gmail.com>\nhu - Sandor Lisovszki <lisovszki at dunakanyar.net>\nnl - Pascal De Vuyst <pascal.devuyst at gmail.com>\npl - Tomasz Dominikowski <dominikowski at gmail.com>\npt_BR - Danilo Martins <mawkee at gmail.com>\nru - mavka <mavka at justos.org>\nit - Daniele Maggio <dado84 at freemail.it>\nzh_CN - Jayden Suen <no.sun at 163.com>')
+-		gtk.about_dialog_set_url_hook(self.show_website, "http://mirageiv.berlios.de")
++		# gtk.about_dialog_set_url_hook(self.show_website, "http://mirageiv.berlios.de")
++		self.about_dialog.connect('activate-link',  self.show_website, "http://mirageiv.berlios.de")
+ 		self.about_dialog.set_website_label("http://mirageiv.berlios.de")
++		self.about_dialog.set_website("http://mirageiv.berlios.de")
+ 		icon_path = self.find_path('mirage.png')
+ 		try:
+-			icon_pixbuf = gtk.gdk.pixbuf_new_from_file(icon_path)
++			icon_pixbuf = GdkPixbuf.Pixbuf.new_from_file(icon_path)
+ 			self.about_dialog.set_logo(icon_pixbuf)
+ 		except:
+ 			pass
+@@ -2964,7 +3034,7 @@ class Base:
+ 		self.about_dialog.connect('delete_event', self.close_about)
+ 		self.about_dialog.show_all()
+ 
+-	def show_website(self, dialog, blah, link):
++	def show_website(self, dialog, link, blah):
+ 		self.browser_load(link)
+ 
+ 	def show_help(self, action):
+@@ -2989,7 +3059,7 @@ class Base:
+ 							try:
+ 								pid = subprocess.Popen(["opera", docslink]).pid
+ 							except:
+-								error_dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, _('Unable to launch a suitable browser.'))
++								error_dialog = gtk.MessageDialog(parent=self.window, modal=True, message_type=gtk.MessageType.WARNING, buttons=gtk.ButtonsType.CLOSE, text=_('Unable to launch a suitable browser.'))
+ 								error_dialog.run()
+ 								error_dialog.destroy()
+ 
+@@ -2998,41 +3068,62 @@ class Base:
+ 		return True
+ 
+ 	def mousewheel_scrolled(self, widget, event):
+-		if event.type == gtk.gdk.SCROLL:
++		if event.type == gdk.EventType.SCROLL:
+ 			# Zooming of the image by Ctrl-mousewheel
+-			if event.state & gtk.gdk.CONTROL_MASK:
+-				if event.direction == gtk.gdk.SCROLL_UP:
++			delta_y = 0.0
++			if event.direction == gdk.ScrollDirection.SMOOTH:
++				delta_y = event.get_scroll_deltas()[2]
++				if (delta_y == 0.0):
++					return True
++			if event.state & gdk.ModifierType.CONTROL_MASK:
++				if event.direction == gdk.ScrollDirection.UP:
+ 					self.zoom_in(None)
+-				elif event.direction == gtk.gdk.SCROLL_DOWN:
++				elif event.direction == gdk.ScrollDirection.DOWN:
+ 					self.zoom_out(None)
++				elif event.direction == gdk.ScrollDirection.SMOOTH:
++					if delta_y > 0.0:
++						self.zoom_out(None)
++					else:
++						self.zoom_in(None)
+ 				return True
+ 			# Navigation of images with mousewheel:
+ 			else:
+-				if event.direction == gtk.gdk.SCROLL_UP:
++				if event.direction == gdk.ScrollDirection.UP:
+ 					self.goto_prev_image(None)
+-				elif event.direction == gtk.gdk.SCROLL_DOWN:
++				elif event.direction == gdk.ScrollDirection.DOWN:
+ 					self.goto_next_image(None)
++				elif event.direction == gdk.ScrollDirection.SMOOTH:
++					if delta_y > 0.0:
++						self.goto_next_image(None)
++					else:
++						self.goto_prev_image(None)
+ 				return True
+ 
++	def gdk_window_get_pointer(self, gdkwindow):
++		# return gdkwindow.get_pointer() <- this is deprecated
++		display = gdkwindow.get_display()
++		pointer = display.get_default_seat().get_pointer()
++		return gdkwindow.get_device_position(pointer)
++
+ 	def mouse_moved(self, widget, event):
+ 		# This handles the panning of the image
+ 		if event.is_hint:
+-			x, y, state = event.window.get_pointer()
++			returned_window, x, y, state = self.gdk_window_get_pointer(event.window)
+ 		else:
+ 			state = event.state
+ 		x, y = event.x_root, event.y_root
+-		if (state & gtk.gdk.BUTTON2_MASK) or (state & gtk.gdk.BUTTON1_MASK):
++		if (state & gdk.ModifierType.BUTTON2_MASK) or (state & gdk.ModifierType.BUTTON1_MASK):
+ 			# Prevent self.expose_event() from potentially further changing the
+ 			# adjustments upon the adjustment value changes
+ 			self.updating_adjustments = True
+ 			xadjust = self.layout.get_hadjustment()
+-			newx = xadjust.value + (self.prevmousex - x)
+-			if newx >= xadjust.lower and newx <= xadjust.upper - xadjust.page_size:
++			newx = xadjust.get_value() + (self.prevmousex - x)
++			if newx >= xadjust.get_lower() and newx <= xadjust.get_upper() - xadjust.get_page_size():
+ 				xadjust.set_value(newx)
+ 				self.layout.set_hadjustment(xadjust)
+ 			yadjust = self.layout.get_vadjustment()
+-			newy = yadjust.value + (self.prevmousey - y)
+-			if newy >= yadjust.lower and newy <= yadjust.upper - yadjust.page_size:
++			newy = yadjust.get_value() + (self.prevmousey - y)
++			if newy >= yadjust.get_lower() and newy <= yadjust.get_upper() - yadjust.get_page_size():
+ 				yadjust.set_value(newy)
+ 				self.layout.set_vadjustment(yadjust)
+ 			self.updating_adjustments = False
+@@ -3042,11 +3133,11 @@ class Base:
+ 			# Show cursor on movement, then hide after 2 seconds of no movement
+ 			self.change_cursor(None)
+ 			if not self.slideshow_controls_visible:
+-				gobject.source_remove(self.timer_id)
++				self.source_try_remove(self.timer_id)
+ 				if not self.closing_app:
+ 					while gtk.events_pending():
+ 						gtk.main_iteration()
+-				self.timer_id = gobject.timeout_add(2000, self.hide_cursor)
++				self.timer_id = GLib.timeout_add(2000, self.hide_cursor)
+ 			if y > 0.9*self.available_image_height():
+ 				self.slideshow_controls_show()
+ 			else:
+@@ -3060,10 +3151,10 @@ class Base:
+ 				self.prevmousex = event.x_root
+ 				self.prevmousey = event.y_root
+ 				if (self.hscroll.get_property('visible')==True or self.vscroll.get_property('visible')==True) :
+-					self.change_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
++					self.change_cursor(gdk.Cursor(gdk.CursorType.FLEUR))
+ 			# Right-click popup:
+ 			elif self.image_loaded and event.button == 3:
+-				self.UIManager.get_widget('/Popup').popup(None, None, None, event.button, event.time)
++				menu = self.UIManager.get_widget('/Popup').popup(None, None, None, None, event.button, event.time)
+ 		return True
+ 
+ 	def button_released(self, widget, event):
+@@ -3277,10 +3368,10 @@ class Base:
+ 		if not pixbuf.get_has_alpha():
+ 			crop_pixbuf = pixbuf.scale_simple(image_width, image_height, zoom_quality)
+ 		else:
+-			colormap = self.imageview.get_colormap()
+-			light_grey = colormap.alloc_color('#666666', True, True)
+-			dark_grey = colormap.alloc_color('#999999', True, True)
+-			crop_pixbuf = pixbuf.composite_color_simple(image_width, image_height, zoom_quality, 255, 8, light_grey.pixel, dark_grey.pixel)
++			#colormap = self.imageview.get_colormap()
++			#light_grey = colormap.alloc_color('#666666', True, True)
++			#dark_grey = colormap.alloc_color('#999999', True, True)
++			crop_pixbuf = pixbuf.composite_color_simple(image_width, image_height, zoom_quality, 255, 8, 0x666666, 0x999999)
+ 		return (crop_pixbuf, image_width, image_height)
+ 
+ 	def pixbuf_add_border(self, pix):
+@@ -3289,7 +3380,7 @@ class Base:
+ 		try:
+ 			width = pix.get_width()
+ 			height = pix.get_height()
+-			newpix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width+2, height+2)
++			newpix = GdkPixbuf.Pixbuf.new(colorspace=GdkPixbuf.Colorspace.RGB, has_alpha=True, bits_per_sample=8, width=width+2, height=height+2)
+ 			newpix.fill(0x858585ff)
+ 			pix.copy_area(0, 0, width, height, newpix, 1, 1)
+ 			return newpix
+@@ -3297,33 +3388,34 @@ class Base:
+ 			return pix
+ 
+ 	def crop_image(self, action):
+-		dialog = gtk.Dialog(_("Crop Image"), self.window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+-		cropbutton = dialog.add_button(_("C_rop"), gtk.RESPONSE_ACCEPT)
++		dialog = gtk.Dialog(title=_("Crop Image"), parent=self.window, modal=True)
++		dialog.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.REJECT)
++		cropbutton = dialog.add_button(_("C_rop"), gtk.ResponseType.ACCEPT)
+ 		cropimage = gtk.Image()
+-		cropimage.set_from_stock(gtk.STOCK_OK, gtk.ICON_SIZE_BUTTON)
++		cropimage.set_from_stock(gtk.STOCK_OK, gtk.IconSize.BUTTON)
+ 		cropbutton.set_image(cropimage)
+ 		image = gtk.DrawingArea()
+ 		crop_pixbuf, image_width, image_height = self.get_pixbuf_of_size(self.currimg_pixbuf_original, 400, self.zoom_quality)
+ 		image.set_size_request(image_width, image_height)
+ 		hbox = gtk.HBox()
+-		hbox.pack_start(gtk.Label(), expand=True)
+-		hbox.pack_start(image, expand=False)
+-		hbox.pack_start(gtk.Label(), expand=True)
++		hbox.pack_start(gtk.Label(), expand=True, fill=True, padding=0)
++		hbox.pack_start(image, expand=False, fill=True, padding=0)
++		hbox.pack_start(gtk.Label(), expand=True, fill=True, padding=0)
+ 		vbox_left = gtk.VBox()
+-		x_adj = gtk.Adjustment(0, 0, self.currimg_pixbuf_original.get_width(), 1, 10, 0)
+-		x = gtk.SpinButton(x_adj, 0, 0)
++		x_adj = gtk.Adjustment(value=0, lower=0, upper=self.currimg_pixbuf_original.get_width(), step_increment=1, page_increment=10, page_size=0)
++		x = gtk.SpinButton(adjustment = x_adj, climb_rate =  0, digits =  0)
+ 		x.set_numeric(True)
+-		x.set_update_policy(gtk.UPDATE_IF_VALID)
++		x.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		x.set_wrap(False)
+-		x_label = gtk.Label("X:")
++		x_label = gtk.Label(label="X:")
+ 		x_label.set_alignment(0, 0.7)
+-		y_adj = gtk.Adjustment(0, 0, self.currimg_pixbuf_original.get_height(), 1, 10, 0)
+-		y = gtk.SpinButton(y_adj, 0, 0)
++		y_adj = gtk.Adjustment(value=0, lower=0, upper=self.currimg_pixbuf_original.get_height(), step_increment=1, page_increment=10, page_size=0)
++		y = gtk.SpinButton(adjustment = y_adj, climb_rate =  0, digits =  0)
+ 		y.set_numeric(True)
+-		y.set_update_policy(gtk.UPDATE_IF_VALID)
++		y.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		y.set_wrap(False)
+-		y_label = gtk.Label("Y:")
+-		x_label.set_size_request(y_label.size_request()[0], -1)
++		y_label = gtk.Label(label="Y:")
++		x_label.set_size_request(y_label.size_request().width, -1)
+ 		hbox_x = gtk.HBox()
+ 		hbox_y = gtk.HBox()
+ 		hbox_x.pack_start(x_label, False, False, 10)
+@@ -3335,20 +3427,20 @@ class Base:
+ 		vbox_left.pack_start(hbox_x, False, False, 0)
+ 		vbox_left.pack_start(hbox_y, False, False, 0)
+ 		vbox_right = gtk.VBox()
+-		width_adj = gtk.Adjustment(self.currimg_pixbuf_original.get_width(), 1, self.currimg_pixbuf_original.get_width(), 1, 10, 0)
+-		width = gtk.SpinButton(width_adj, 0, 0)
++		width_adj = gtk.Adjustment(value=self.currimg_pixbuf_original.get_width(), lower=1, upper=self.currimg_pixbuf_original.get_width(), step_increment=1, page_increment=10, page_size=0)
++		width = gtk.SpinButton(adjustment = width_adj, climb_rate =  0, digits =  0)
+ 		width.set_numeric(True)
+-		width.set_update_policy(gtk.UPDATE_IF_VALID)
++		width.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		width.set_wrap(False)
+-		width_label = gtk.Label(_("Width:"))
++		width_label = gtk.Label(label=_("Width:"))
+ 		width_label.set_alignment(0, 0.7)
+-		height_adj = gtk.Adjustment(self.currimg_pixbuf_original.get_height(), 1, self.currimg_pixbuf_original.get_height(), 1, 10, 0)
+-		height = gtk.SpinButton(height_adj, 0, 0)
++		height_adj = gtk.Adjustment(value=self.currimg_pixbuf_original.get_height(), lower=1, upper=self.currimg_pixbuf_original.get_height(), step_increment=1, page_increment=10, page_size=0)
++		height = gtk.SpinButton(adjustment = height_adj, climb_rate =  0, digits =  0)
+ 		height.set_numeric(True)
+-		height.set_update_policy(gtk.UPDATE_IF_VALID)
++		height.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		height.set_wrap(False)
+-		height_label = gtk.Label(_("Height:"))
+-		width_label.set_size_request(height_label.size_request()[0], -1)
++		height_label = gtk.Label(label=_("Height:"))
++		width_label.set_size_request(height_label.size_request().width, -1)
+ 		height_label.set_alignment(0, 0.7)
+ 		hbox_width = gtk.HBox()
+ 		hbox_height = gtk.HBox()
+@@ -3359,33 +3451,35 @@ class Base:
+ 		vbox_right.pack_start(hbox_width, False, False, 0)
+ 		vbox_right.pack_start(hbox_height, False, False, 0)
+ 		hbox2 = gtk.HBox()
+-		hbox2.pack_start(gtk.Label(), expand=True)
++		hbox2.pack_start(gtk.Label(), expand=True, fill=True, padding=0)
+ 		hbox2.pack_start(vbox_left, False, False, 0)
+ 		hbox2.pack_start(vbox_right, False, False, 0)
+-		hbox2.pack_start(gtk.Label(), expand=True)
++		hbox2.pack_start(gtk.Label(), expand=True, fill=True, padding=0)
+ 		dialog.vbox.pack_start(hbox, False, False, 0)
+ 		dialog.vbox.pack_start(hbox2, False, False, 15)
+ 		dialog.set_resizable(False)
+ 		dialog.vbox.show_all()
+-		image.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_MOTION_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
+-		image.connect("expose-event", self.crop_image_expose_cb, crop_pixbuf, image_width, image_height)
+-		image.connect("motion_notify_event", self.crop_image_mouse_moved, image, 0, 0, x, y, width, height, image_width, image_height, width_adj, height_adj)
++		image.set_events(gdk.EventMask.POINTER_MOTION_MASK | gdk.EventMask.POINTER_MOTION_HINT_MASK | gdk.EventMask.BUTTON_PRESS_MASK | gdk.EventMask.BUTTON_MOTION_MASK | gdk.EventMask.BUTTON_RELEASE_MASK)
++		# FIXME
++		#image.connect("expose-event", self.crop_image_expose_cb, crop_pixbuf, image_width, image_height)
++		image.connect("draw", self.crop_image_expose_cb, crop_pixbuf, image_width, image_height, True)
++		image.connect("motion_notify_event", self.crop_image_mouse_moved, image, crop_pixbuf, 0, 0, x, y, width, height, image_width, image_height, width_adj, height_adj)
+ 		image.connect("button_press_event", self.crop_image_button_press, image)
+ 		image.connect("button_release_event", self.crop_image_button_release)
+-		self.x_changed = x.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, 0)
+-		self.y_changed = y.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, 1)
+-		self.width_changed = width.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, 2)
+-		self.height_changed = height.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, 3)
++		self.x_changed = x.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, crop_pixbuf, 0)
++		self.y_changed = y.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, crop_pixbuf, 1)
++		self.width_changed = width.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, crop_pixbuf, 2)
++		self.height_changed = height.connect('value-changed', self.crop_value_changed, x, y, width, height, width_adj, height_adj, image_width, image_height, image, crop_pixbuf, 3)
+ 		image.realize()
+ 		self.crop_rectangle = [0, 0]
+ 		self.drawing_crop_rectangle = False
+ 		self.update_rectangle = False
+ 		self.rect = None
+ 		response = dialog.run()
+-		if response == gtk.RESPONSE_ACCEPT:
++		if response == gtk.ResponseType.ACCEPT:
+ 			dialog.destroy()
+ 			if self.rect != None:
+-				temp_pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, self.currimg_pixbuf_original.get_has_alpha(), 8, self.coords[2], self.coords[3])
++				temp_pixbuf = GdkPixbuf.Pixbuf.new(colorspace=GdkPixbuf.Colorspace.RGB, has_alpha=self.currimg_pixbuf_original.get_has_alpha(), bits_per_sample=8, width=self.coords[2], height=self.coords[3])
+ 				self.currimg_pixbuf_original.copy_area(self.coords[0], self.coords[1], self.coords[2], self.coords[3], temp_pixbuf, 0, 0)
+ 				self.currimg_pixbuf_original = temp_pixbuf
+ 				del temp_pixbuf
+@@ -3395,7 +3489,7 @@ class Base:
+ 		else:
+ 			dialog.destroy()
+ 
+-	def crop_value_changed(self, currspinbox, x, y, width, height, width_adj, height_adj, image_width, image_height, image, type):
++	def crop_value_changed(self, currspinbox, x, y, width, height, width_adj, height_adj, image_width, image_height, image, pixbuf, type):
+ 		if type == 0:   # X
+ 			if x.get_value() + width.get_value() > self.currimg_pixbuf_original.get_width():
+ 				width.handler_block(self.width_changed)
+@@ -3413,22 +3507,45 @@ class Base:
+ 		y2 = int(round(float(self.coords[3])/self.currimg_pixbuf_original.get_height()*image_height, 0)) + self.crop_rectangle[1]
+ 		self.drawing_crop_rectangle = True
+ 		self.update_rectangle = True
+-		self.crop_image_mouse_moved(None, None, image, x2, y2, x, y, width, height, image_width, image_height, width_adj, height_adj)
++		self.crop_image_mouse_moved(None, None, image, pixbuf, x2, y2, x, y, width, height, image_width, image_height, width_adj, height_adj)
+ 		self.update_rectangle = False
+ 		self.drawing_crop_rectangle = False
+ 
+-	def crop_image_expose_cb(self, image, event, pixbuf, width, height):
+-		image.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0, width, height)
++	# FIXME
++	def crop_image_expose_cb(self, image, cr, pixbuf, width, height, use_internal_cr):
++		#image.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0, width, height)
++		if (use_internal_cr == False):
++			cr = gdk.cairo_create(image.get_window())
++		gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0)
++		cr.paint()
++		if (use_internal_cr == True):
++			del cr
++
++	def gdk_rectangle(self, x,y,width,height):
++		rect = gdk.Rectangle()
++		rect.x = x
++		rect.y = y
++		rect.width = width
++		rect.height = height
++		return rect
+ 
+-	def crop_image_mouse_moved(self, widget, event, image, x2, y2, x, y, width, height, image_width, image_height, width_adj, height_adj):
++	# FIXME
++	def crop_image_mouse_moved(self, widget, event, image, pixbuf, x2, y2, x, y, width, height, image_width, image_height, width_adj, height_adj):
+ 		if event != None:
+-			x2, y2, state = event.window.get_pointer()
++			returned_window, x2, y2, state = self.gdk_window_get_pointer(event.window)
+ 		if self.drawing_crop_rectangle:
+ 			if self.crop_rectangle != None or self.update_rectangle:
+-				gc = image.window.new_gc(function=gtk.gdk.INVERT)
++				# FIXME
++				#gc = image.window.new_gc(function=gtk.gdk.INVERT)
+ 				if self.rect != None:
+ 					# Get rid of the previous drawn rectangle:
+-					image.window.draw_rectangle(gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3])
++					#image.window.draw_rectangle(gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3])
++					# FIXME
++					cr = gdk.cairo_create(image.get_window())
++					gdk.cairo_rectangle(cr, self.gdk_rectangle(self.rect[0], self.rect[1], self.rect[2], self.rect[3]))
++					cr.stroke()
++					del cr
++
+ 				self.rect = [0, 0, 0, 0]
+ 				if self.crop_rectangle[0] > x2:
+ 					self.rect[0] = x2
+@@ -3442,7 +3559,16 @@ class Base:
+ 				else:
+ 					self.rect[1] = self.crop_rectangle[1]
+ 					self.rect[3] = y2-self.crop_rectangle[1]
+-				image.window.draw_rectangle(gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3])
++				# FIXME
++				# FIXME
++				# Here, we redraw all pixels in the window instead of just removing previous rectangle
++				# Any better way??
++				#image.window.draw_rectangle(gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3])
++				cr = gdk.cairo_create(image.get_window())
++				self.crop_image_expose_cb(image, cr, pixbuf, self.rect[2], self.rect[3], False)
++				gdk.cairo_rectangle(cr, self.gdk_rectangle(self.rect[0], self.rect[1], self.rect[2], self.rect[3]))
++				cr.stroke()
++				del cr
+ 				# Convert the rectangle coordinates of the current image
+ 				# to coordinates of pixbuf_original
+ 				if self.rect[0] < 0:
+@@ -3477,48 +3603,56 @@ class Base:
+ 				height.handler_unblock(self.height_changed)
+ 
+ 	def crop_image_button_press(self, widget, event, image):
+-		x, y, state = event.window.get_pointer()
+-		if (state & gtk.gdk.BUTTON1_MASK):
++		returned_window, x, y, state = self.gdk_window_get_pointer(event.window)
++		if (state & gdk.ModifierType.BUTTON1_MASK):
+ 			self.drawing_crop_rectangle = True
+ 			self.crop_rectangle = [x, y]
+-			gc = image.window.new_gc(function=gtk.gdk.INVERT)
++			# FIXME
++			#gc = image.window.new_gc(function=gtk.gdk.INVERT)
+ 			if self.rect != None:
+ 				# Get rid of the previous drawn rectangle:
+-				image.window.draw_rectangle(gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3])
++				# FIXME
++				#image.window.draw_rectangle(gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3])
++				cr = gdk.cairo_create(image.get_window())
++				gdk.cairo_rectangle(cr, self.gdk_rectangle(self.rect[0], self.rect[1], self.rect[2], self.rect[3]))
++				cr.stroke()
++				del cr
+ 				self.rect = None
+ 
+ 	def crop_image_button_release(self, widget, event):
+-		x, y, state = event.window.get_pointer()
+-		if not (state & gtk.gdk.BUTTON1_MASK):
++		returned_window, x, y, state = self.gdk_window_get_pointer(event.window)
++		if not (state & gdk.ModifierType.BUTTON1_MASK):
+ 			self.drawing_crop_rectangle = False
+ 
+ 	def saturation(self, action):
+-		dialog = gtk.Dialog(_("Saturation"), self.window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+-		resizebutton = dialog.add_button(_("_Saturate"), gtk.RESPONSE_ACCEPT)
++		dialog = gtk.Dialog(title=_("Saturation"), parent=self.window, modal=True)
++		dialog.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.REJECT)
++		resizebutton = dialog.add_button(_("_Saturate"), gtk.ResponseType.ACCEPT)
+ 		resizeimage = gtk.Image()
+-		resizeimage.set_from_stock(gtk.STOCK_OK, gtk.ICON_SIZE_BUTTON)
++		resizeimage.set_from_stock(gtk.STOCK_OK, gtk.IconSize.BUTTON)
+ 		resizebutton.set_image(resizeimage)
+ 		scale = gtk.HScale()
+ 		scale.set_draw_value(False)
+-		scale.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
++		#scale.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
+ 		scale.set_range(0, 2)
+ 		scale.set_increments(0.1, 0.5)
+ 		scale.set_value(1)
+-		scale.connect('value-changed', self.saturation_preview)
+-		label = gtk.Label(_("Saturation level:"))
++		#scale.connect('value-changed', self.saturation_preview)
++		scale.connect('button-release-event', self.saturation_preview)
++		label = gtk.Label(label=_("Saturation level:"))
+ 		label.set_alignment(0, 0.5)
+ 		hbox1 = gtk.HBox()
+ 		hbox1.pack_start(label, True, True, 10)
+ 		hbox2 = gtk.HBox()
+ 		hbox2.pack_start(scale, True, True, 20)
+-		dialog.vbox.pack_start(gtk.Label(" "))
+-		dialog.vbox.pack_start(hbox1, False)
++		dialog.vbox.pack_start(gtk.Label(label=" "), True, True, 0)
++		dialog.vbox.pack_start(hbox1, False, True, 0)
+ 		dialog.vbox.pack_start(hbox2, True, True, 10)
+-		dialog.vbox.pack_start(gtk.Label(" "))
+-		dialog.set_default_response(gtk.RESPONSE_ACCEPT)
++		dialog.vbox.pack_start(gtk.Label(label=" "), True, True, 0)
++		dialog.set_default_response(gtk.ResponseType.ACCEPT)
+ 		dialog.vbox.show_all()
+ 		response = dialog.run()
+-		if response == gtk.RESPONSE_ACCEPT:
++		if response == gtk.ResponseType.ACCEPT:
+ 			self.currimg_pixbuf_original.saturate_and_pixelate(self.currimg_pixbuf_original, scale.get_value(), False)
+ 			self.currimg_pixbuf.saturate_and_pixelate(self.currimg_pixbuf, scale.get_value(), False)
+ 			self.imageview.set_from_pixbuf(self.currimg_pixbuf)
+@@ -3528,7 +3662,8 @@ class Base:
+ 			self.imageview.set_from_pixbuf(self.currimg_pixbuf)
+ 			dialog.destroy()
+ 
+-	def saturation_preview(self, range):
++	#def saturation_preview(self, range):
++	def saturation_preview(self, range, event):
+ 		while gtk.events_pending():
+ 			gtk.main_iteration()
+ 		try:
+@@ -3542,36 +3677,37 @@ class Base:
+ 		gc.collect()
+ 
+ 	def resize_image(self, action):
+-		dialog = gtk.Dialog(_("Resize Image"), self.window, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
+-		resizebutton = dialog.add_button(_("_Resize"), gtk.RESPONSE_ACCEPT)
++		dialog = gtk.Dialog(title=_("Resize Image"), parent=self.window, modal=True)
++		dialog.add_buttons(gtk.STOCK_CANCEL, gtk.ResponseType.REJECT)
++		resizebutton = dialog.add_button(_("_Resize"), gtk.ResponseType.ACCEPT)
+ 		resizeimage = gtk.Image()
+-		resizeimage.set_from_stock(gtk.STOCK_OK, gtk.ICON_SIZE_BUTTON)
++		resizeimage.set_from_stock(gtk.STOCK_OK, gtk.IconSize.BUTTON)
+ 		resizebutton.set_image(resizeimage)
+ 		hbox_width = gtk.HBox()
+-		width_adj = gtk.Adjustment(self.currimg_pixbuf_original.get_width(), 1, 100000000000, 1, 10, 0)
+-		width = gtk.SpinButton(width_adj, 0, 0)
++		width_adj = gtk.Adjustment(value=self.currimg_pixbuf_original.get_width(), lower=1, upper=100000000000, step_increment=1, page_increment=10, page_size=0)
++		width = gtk.SpinButton(adjustment = width_adj, climb_rate =  0, digits =  0)
+ 		width.set_numeric(True)
+-		width.set_update_policy(gtk.UPDATE_IF_VALID)
++		width.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		width.set_wrap(False)
+-		width_label = gtk.Label(_("Width:"))
++		width_label = gtk.Label(label=_("Width:"))
+ 		width_label.set_alignment(0, 0.7)
+ 		hbox_width.pack_start(width_label, False, False, 10)
+ 		hbox_width.pack_start(width, False, False, 0)
+-		hbox_width.pack_start(gtk.Label(_("pixels")), False, False, 10)
++		hbox_width.pack_start(gtk.Label(label=_("pixels")), False, False, 10)
+ 		hbox_height = gtk.HBox()
+-		height_adj = gtk.Adjustment(self.currimg_pixbuf_original.get_height(), 1, 100000000000, 1, 10, 0)
+-		height = gtk.SpinButton(height_adj, 0, 0)
++		height_adj = gtk.Adjustment(value=self.currimg_pixbuf_original.get_height(), lower=1, upper=100000000000, step_increment=1, page_increment=10, page_size=0)
++		height = gtk.SpinButton(adjustment = height_adj, climb_rate =  0, digits =  0)
+ 		height.set_numeric(True)
+-		height.set_update_policy(gtk.UPDATE_IF_VALID)
++		height.set_update_policy(gtk.SpinButtonUpdatePolicy.IF_VALID)
+ 		height.set_wrap(False)
+-		height_label = gtk.Label(_("Height:"))
+-		width_label.set_size_request(height_label.size_request()[0], -1)
++		height_label = gtk.Label(label=_("Height:"))
++		width_label.set_size_request(height_label.size_request().width, -1)
+ 		height_label.set_alignment(0, 0.7)
+ 		hbox_height.pack_start(height_label, False, False, 10)
+ 		hbox_height.pack_start(height, False, False, 0)
+-		hbox_height.pack_start(gtk.Label(_("pixels")), False, False, 10)
++		hbox_height.pack_start(gtk.Label(label=_("pixels")), False, False, 10)
+ 		hbox_aspect = gtk.HBox()
+-		aspect_checkbox = gtk.CheckButton(_("Preserve aspect ratio"))
++		aspect_checkbox = gtk.CheckButton(label=_("Preserve aspect ratio"))
+ 		aspect_checkbox.set_active(self.preserve_aspect)
+ 		hbox_aspect.pack_start(aspect_checkbox, False, False, 10)
+ 		vbox = gtk.VBox()
+@@ -3582,7 +3718,7 @@ class Base:
+ 		vbox.pack_start(hbox_aspect, False, False, 0)
+ 		vbox.pack_start(gtk.Label(), False, False, 0)
+ 		hbox_total = gtk.HBox()
+-		animtest = gtk.gdk.PixbufAnimation(self.currimg_name)
++		animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.currimg_name)
+ 		if animtest.is_static_image():
+ 			pixbuf, image_width, image_height = self.get_pixbuf_of_size(self.currimg_pixbuf_original, 96, self.zoom_quality)
+ 		else:
+@@ -3595,10 +3731,10 @@ class Base:
+ 		width.connect('value-changed', self.preserve_image_aspect, "width", height)
+ 		height.connect('value-changed', self.preserve_image_aspect, "height", width)
+ 		aspect_checkbox.connect('toggled', self.aspect_ratio_toggled, width, height)
+-		dialog.set_default_response(gtk.RESPONSE_ACCEPT)
++		dialog.set_default_response(gtk.ResponseType.ACCEPT)
+ 		dialog.vbox.show_all()
+ 		response = dialog.run()
+-		if response == gtk.RESPONSE_ACCEPT:
++		if response == gtk.ResponseType.ACCEPT:
+ 			pixelheight = height.get_value_as_int()
+ 			pixelwidth = width.get_value_as_int()
+ 			dialog.destroy()
+@@ -3651,7 +3787,7 @@ class Base:
+ 	def goto_image(self, location, action):
+ 		# location can be "LAST", "FIRST", "NEXT", "PREV", "RANDOM", or a number
+ 		if self.slideshow_mode and action != "ss":
+-			gobject.source_remove(self.timer_delay)
++			self.source_try_remove(self.timer_delay)
+ 		if ((location=="PREV" or location=="NEXT" or location=="RANDOM") and len(self.image_list) > 1) or (location=="FIRST" and (len(self.image_list) > 1 and self.curr_img_in_list != 0)) or (location=="LAST" and (len(self.image_list) > 1 and self.curr_img_in_list != len(self.image_list)-1)) or valid_int(location):
+ 			self.load_new_image_stop_now()
+ 			cancel = self.autosave_image()
+@@ -3712,17 +3848,18 @@ class Base:
+ 					if self.fullscreen_mode:
+ 						self.change_cursor(None)
+ 					if location == "PREV":
+-						dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("You are viewing the first image in the list. Wrap around to the last image?"))
++						dialog = gtk.MessageDialog(parent=self.window, modal=True, destroy_with_parent=True, message_type=gtk.MessageType.QUESTION, buttons=gtk.ButtonsType.YES_NO, text=_("You are viewing the first image in the list. Wrap around to the last image?"))
+ 					elif location == "NEXT":
+-						dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("You are viewing the last image in the list. Wrap around to the first image?"))
++						dialog = gtk.MessageDialog(parent=self.window, modal=True, destroy_with_parent=True, message_type=gtk.MessageType.QUESTION, buttons=gtk.ButtonsType.YES_NO, text=_("You are viewing the last image in the list. Wrap around to the first image?"))
+ 					elif location == "RANDOM":
+-						dialog = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("All images have been viewed. Would you like to cycle through the images again?"))
++						dialog = gtk.MessageDialog(parent=self.window, modal=True, destroy_with_parent=True, message_type=gtk.MessageType.QUESTION, buttons=gtk.ButtonsType.YES_NO, text=_("All images have been viewed. Would you like to cycle through the images again?"))
+ 					dialog.set_title(_("Wrap?"))
+-					dialog.label.set_property('can-focus', False)
+-					dialog.set_default_response(gtk.RESPONSE_YES)
++					# FIXME
++					#dialog.label.set_property('can-focus', False)
++					dialog.set_default_response(gtk.ResponseType.YES)
+ 					self.user_prompt_visible = True
+ 					response = dialog.run()
+-					if response == gtk.RESPONSE_YES:
++					if response == gtk.ResponseType.YES:
+ 						if location == "PREV":
+ 							self.curr_img_in_list = len(self.image_list)-1
+ 						elif location == "NEXT":
+@@ -3755,18 +3892,18 @@ class Base:
+ 				prev_img = self.curr_img_in_list
+ 				self.curr_img_in_list = int(location)
+ 			if not self.fullscreen_mode and (not self.slideshow_mode or (self.slideshow_mode and action != "ss")):
+-				self.change_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
++				self.change_cursor(gdk.Cursor(gdk.CursorType.WATCH))
+ 			if location == "PREV" or (valid_int(location) and int(location) == prev_img-1):
+-				self.load_when_idle = gobject.idle_add(self.load_new_image, True, False, True, True, True, True)
++				self.load_when_idle = GLib.idle_add(self.load_new_image, True, False, True, True, True, True)
+ 			else:
+-				self.load_when_idle = gobject.idle_add(self.load_new_image, False, False, True, True, True, True)
++				self.load_when_idle = GLib.idle_add(self.load_new_image, False, False, True, True, True, True)
+ 			self.set_go_navigation_sensitivities(False)
+ 			if self.slideshow_mode:
+ 				if self.curr_slideshow_random:
+-					self.timer_delay = gobject.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_random_image, "ss")
++					self.timer_delay = GLib.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_random_image, "ss")
+ 				else:
+-					self.timer_delay = gobject.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_next_image, "ss")
+-			gobject.idle_add(self.thumbpane_select, self.curr_img_in_list)
++					self.timer_delay = GLib.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_next_image, "ss")
++			GLib.idle_add(self.thumbpane_select, self.curr_img_in_list)
+ 		
+ 	def set_go_navigation_sensitivities(self, skip_initial_check):
+ 		# setting skip_image_list_check to True is useful when calling from
+@@ -3816,7 +3953,7 @@ class Base:
+ 		else:
+ 			self.currmg_name = filename
+ 		if self.verbose and self.currimg_name != "":
+-			print _("Loading: %s") % self.currimg_name
++			print (_("Loading: %s") % self.currimg_name)
+ 		self.update_title()
+ 		self.put_error_image_to_window()
+ 		self.image_loaded = False
+@@ -3825,29 +3962,32 @@ class Base:
+ 			if not self.fullscreen_mode:
+ 				self.change_cursor(None)
+ 
+-	def load_new_image_stop_now(self):
+-		try:
+-			gobject.source_remove(self.load_when_idle)
+-		except:
+-			pass
+-		try:
+-			gobject.source_remove(self.preload_when_idle)
+-		except:
+-			pass
++	def source_try_remove(self, source_id):
++		if source_id <= 0:
++			return
++		main_context = GLib.MainContext.default()
++		source = main_context.find_source_by_id(source_id)
++		if source == None:
++			return
+ 		try:
+-			gobject.source_remove(self.preload_when_idle2)
++			GLib.source_remove(source_id)
+ 		except:
+ 			pass
+ 
++	def load_new_image_stop_now(self):
++		self.source_try_remove(self.load_when_idle)
++		self.source_try_remove(self.preload_when_idle)
++		self.source_try_remove(self.preload_when_idle2)
++
+ 	def load_new_image(self, check_prev_last, use_current_pixbuf_original, reset_cursor, perform_onload_action, preload_next_image_after, preload_prev_image_after):
+ 		try:
+ 			self.load_new_image2(check_prev_last, use_current_pixbuf_original, reset_cursor, perform_onload_action)
+ 		except:
+ 			self.image_load_failed(True)
+ 		if preload_next_image_after:
+-			self.preload_when_idle = gobject.idle_add(self.preload_next_image, False)
++			self.preload_when_idle = GLib.idle_add(self.preload_next_image, False)
+ 		if preload_prev_image_after:
+-			self.preload_when_idle2 = gobject.idle_add(self.preload_prev_image, False)
++			self.preload_when_idle2 = GLib.idle_add(self.preload_prev_image, False)
+ 
+ 	def check_preloadimg_prev_for_existing(self, prev_index, reset_preloadimg_prev_in_list):
+ 		# Determines if preloadimg_prev needs to be updated; if so,
+@@ -3929,7 +4069,7 @@ class Base:
+ 				self.currimg_is_animation = self.preloadimg_prev_is_animation
+ 				used_prev = True
+ 				if self.verbose and self.currimg_name != "":
+-					print _("Loading: %s") % self.currimg_name
++					print (_("Loading: %s") % self.currimg_name)
+ 				self.put_zoom_image_to_window(True)
+ 				if not self.currimg_is_animation:
+ 					self.set_image_sensitivities(True)
+@@ -3946,7 +4086,7 @@ class Base:
+ 				self.currimg_is_animation = self.preloadimg_next_is_animation
+ 				used_next = True
+ 				if self.verbose and self.currimg_name != "":
+-					print _("Loading: %s") % self.currimg_name
++					print (_("Loading: %s") % self.currimg_name)
+ 				self.put_zoom_image_to_window(True)
+ 				if not self.currimg_is_animation:
+ 					self.set_image_sensitivities(True)
+@@ -4009,8 +4149,8 @@ class Base:
+ 			self.currimg_zoomratio = 1
+ 			self.currimg_name = str(self.image_list[self.curr_img_in_list])
+ 			if self.verbose and self.currimg_name != "":
+-				print _("Loading: %s") % self.currimg_name
+-			animtest = gtk.gdk.PixbufAnimation(self.currimg_name)
++				print (_("Loading: %s") % self.currimg_name)
++			animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.currimg_name)
+ 			if animtest.is_static_image() or (use_current_pixbuf_original and not self.currimg_is_animation):
+ 				self.currimg_is_animation = False
+ 				if not use_current_pixbuf_original:
+@@ -4057,7 +4197,7 @@ class Base:
+ 						return
+ 					self.preloadimg_next_in_list = next_index
+ 					self.preloadimg_next_name = str(self.image_list[next_index])
+-					pre_animtest = gtk.gdk.PixbufAnimation(self.preloadimg_next_name)
++					pre_animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.preloadimg_next_name)
+ 					if pre_animtest.is_static_image():
+ 						self.preloadimg_next_is_animation = False
+ 						self.preloadimg_next_pixbuf_original = pre_animtest.get_static_image()
+@@ -4082,15 +4222,15 @@ class Base:
+ 					if not self.preloadimg_next_pixbuf_original.get_has_alpha():
+ 						self.preloadimg_next_pixbuf = self.preloadimg_next_pixbuf_original.scale_simple(self.preloadimg_next_width, self.preloadimg_next_height, self.zoom_quality)
+ 					else:
+-						colormap = self.imageview.get_colormap()
+-						light_grey = colormap.alloc_color('#666666', True, True)
+-						dark_grey = colormap.alloc_color('#999999', True, True)
+-						self.preloadimg_next_pixbuf = self.preloadimg_next_pixbuf_original.composite_color_simple(self.preloadimg_next_width, self.preloadimg_next_height, self.zoom_quality, 255, 8, light_grey.pixel, dark_grey.pixel)
++						#colormap = self.imageview.get_colormap()
++						#light_grey = colormap.alloc_color('#666666', True, True)
++						#dark_grey = colormap.alloc_color('#999999', True, True)
++						self.preloadimg_next_pixbuf = self.preloadimg_next_pixbuf_original.composite_color_simple(self.preloadimg_next_width, self.preloadimg_next_height, self.zoom_quality, 255, 8, 0x666666, 0x999999)
+ 				else:
+ 					self.preloadimg_next_pixbuf = self.preloadimg_next_pixbuf_original
+ 				gc.collect()
+ 				if self.verbose:
+-					print _("Preloading: %s") % self.preloadimg_next_name
++					print (_("Preloading: %s") % self.preloadimg_next_name)
+ 		except:
+ 			self.preloadimg_next_in_list = -1
+ 
+@@ -4109,7 +4249,7 @@ class Base:
+ 						return
+ 					self.preloadimg_prev_in_list = prev_index
+ 					self.preloadimg_prev_name = str(self.image_list[prev_index])
+-					pre_animtest = gtk.gdk.PixbufAnimation(self.preloadimg_prev_name)
++					pre_animtest = GdkPixbuf.PixbufAnimation.new_from_file(self.preloadimg_prev_name)
+ 					if pre_animtest.is_static_image():
+ 						self.preloadimg_prev_is_animation = False
+ 						self.preloadimg_prev_pixbuf_original = pre_animtest.get_static_image()
+@@ -4134,23 +4274,23 @@ class Base:
+ 					if not self.preloadimg_prev_pixbuf_original.get_has_alpha():
+ 						self.preloadimg_prev_pixbuf = self.preloadimg_prev_pixbuf_original.scale_simple(self.preloadimg_prev_width, self.preloadimg_prev_height, self.zoom_quality)
+ 					else:
+-						colormap = self.imageview.get_colormap()
+-						light_grey = colormap.alloc_color('#666666', True, True)
+-						dark_grey = colormap.alloc_color('#999999', True, True)
+-						self.preloadimg_prev_pixbuf = self.preloadimg_prev_pixbuf_original.composite_color_simple(self.preloadimg_prev_width, self.preloadimg_prev_height, self.zoom_quality, 255, 8, light_grey.pixel, dark_grey.pixel)
++						#colormap = self.imageview.get_colormap()
++						#light_grey = colormap.alloc_color('#666666', True, True)
++						#dark_grey = colormap.alloc_color('#999999', True, True)
++						self.preloadimg_prev_pixbuf = self.preloadimg_prev_pixbuf_original.composite_color_simple(self.preloadimg_prev_width, self.preloadimg_prev_height, self.zoom_quality, 255, 8, 0x666666, 0x999999)
+ 				else:
+ 					self.preloadimg_prev_pixbuf = self.preloadimg_prev_pixbuf_original
+ 				gc.collect()
+ 				if self.verbose:
+-					print _("Preloading: %s") % self.preloadimg_prev_name
++					print (_("Preloading: %s") % self.preloadimg_prev_name)
+ 		except:
+ 			self.preloadimg_prev_in_list = -1
+ 
+ 	def change_cursor(self, type):
+-		for i in gtk.gdk.window_get_toplevels():
+-			if i.get_window_type() != gtk.gdk.WINDOW_TEMP and i.get_window_type() != gtk.gdk.WINDOW_CHILD:
++		for i in gdk.Screen.get_default().get_toplevel_windows():
++			if i.get_window_type() != gdk.WindowType.TEMP and i.get_window_type() != gdk.WindowType.CHILD:
+ 				i.set_cursor(type)
+-		self.layout.window.set_cursor(type)
++		self.layout.get_bin_window().set_cursor(type)
+ 
+ 	def expand_filelist_and_load_image(self, inputlist):
+ 		# Takes the current list (i.e. ["pic.jpg", "pic2.gif", "../images"]) and
+@@ -4159,7 +4299,7 @@ class Base:
+ 		first_image_loaded_successfully = False
+ 		self.images_found = 0
+ 		self.stop_now = True # Make sure that any previous search process is stopped
+-		self.change_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
++		self.change_cursor(gdk.Cursor(gdk.CursorType.WATCH))
+ 		# Reset preload images:
+ 		self.preloadimg_next_in_list = -1
+ 		self.preloadimg_prev_in_list = -1
+@@ -4186,6 +4326,8 @@ class Base:
+ 		self.set_go_sensitivities(False)
+ 		# Clean up list (remove preceding "file://" or "file:" and trailing "/")
+ 		for itemnum in range(len(inputlist)):
++			if len(inputlist[itemnum]) == 0:
++				continue
+ 			# Strip off preceding file..
+ 			if inputlist[itemnum].startswith('file://'):
+ 				inputlist[itemnum] = inputlist[itemnum][7:]
+@@ -4202,7 +4344,7 @@ class Base:
+ 					tmpdir = tempfile.mkdtemp(prefix="mirage-") + "/"
+ 					tmpfile = tmpdir + os.path.basename(inputlist[itemnum])
+ 					socket.setdefaulttimeout(5)
+-					urllib.urlretrieve(inputlist[itemnum], tmpfile)
++					urllib.request.urlretrieve(inputlist[itemnum], tmpfile)
+ 					inputlist[itemnum] = tmpfile
+ 				except:
+ 					pass
+@@ -4210,10 +4352,12 @@ class Base:
+ 		if not self.open_hidden_files:
+ 			tmplist = []
+ 			for item in inputlist:
+-				if os.path.basename(item)[0] != '.':
++				if len(item) == 0:
++					pass
++				elif os.path.basename(item)[0] != '.':
+ 					tmplist.append(item)
+ 				elif self.verbose:
+-					print _("Skipping: %s") % item
++					print (_("Skipping: %s") % item)
+ 			inputlist = tmplist
+ 			if len(inputlist) == 0:
+ 				# All files/dirs were hidden, exit..
+@@ -4270,7 +4414,7 @@ class Base:
+ 						self.image_list.append(item)
+ 						if self.verbose:
+ 							self.images_found += 1
+-							print _("Found: %(item)s [%(number)i]") % {'item': item, 'number': self.images_found}
++							print (_("Found: %(item)s [%(number)i]") % {'item': item, 'number': self.images_found})
+ 				else:
+ 					# If it's a directory that was explicitly selected or passed to
+ 					# the program, get all the files in the dir.
+@@ -4291,7 +4435,7 @@ class Base:
+ 									self.set_go_navigation_sensitivities(True)
+ 									go_buttons_enabled = True
+ 									while gtk.events_pending():
+-										gtk.main_iteration(True)
++										gtk.main_iteration_do(True)
+ 								if not first_image_found:
+ 									first_image_found = True
+ 									first_image = self.image_list[itemnum]
+@@ -4303,7 +4447,7 @@ class Base:
+ 					if self.slideshow_mode:
+ 						self.toggle_slideshow(None)
+ 					if self.verbose and self.currimg_name != "":
+-						print _("Loading: %s") % self.currimg_name
++						print (_("Loading: %s") % self.currimg_name)
+ 					try:
+ 						self.load_new_image2(False, False, True, True)
+ 						# Calling load_new_image2 will reset the following two vars
+@@ -4318,7 +4462,7 @@ class Base:
+ 						first_image_loaded_successfully = True
+ 						if not self.closing_app:
+ 							while gtk.events_pending():
+-								gtk.main_iteration(True)
++								gtk.main_iteration_do(True)
+ 					except:
+ 						pass
+ 					if first_image_came_from_dir:
+@@ -4344,7 +4488,7 @@ class Base:
+ 			self.update_title()
+ 			if not self.closing_app:
+ 				while gtk.events_pending():
+-					gtk.main_iteration(True)
++					gtk.main_iteration_do(True)
+ 		if not first_image_loaded_successfully:
+ 			self.image_load_failed(False, init_image)
+ 		self.searching_for_images = False
+@@ -4358,7 +4502,7 @@ class Base:
+ 
+ 	def add_folderlist_images(self, folderlist, go_buttons_enabled):
+ 		if len(folderlist) > 0:
+-			folderlist.sort(locale.strcoll)
++			folderlist.sort(key=functools.cmp_to_key(locale.strcoll))
+ 			folderlist = list(set(folderlist))
+ 			for item in folderlist:
+ 				if not self.closing_app:
+@@ -4370,7 +4514,7 @@ class Base:
+ 		if len(self.image_list) > 0:
+ 			self.set_go_navigation_sensitivities(True)
+ 			self.image_list = list(set(self.image_list))
+-			self.image_list.sort(locale.strcoll)
++			self.image_list.sort(key=functools.cmp_to_key(locale.strcoll))
+ 
+ 	def expand_directory(self, item, stop_when_second_image_found, go_buttons_enabled, update_window_title, print_found_msg):
+ 		if not self.stop_now and not self.closing_app:
+@@ -4381,7 +4525,7 @@ class Base:
+ 			for item2 in os.listdir(item):
+ 				if not self.closing_app and not self.stop_now:
+ 					while gtk.events_pending():
+-						gtk.main_iteration(True)
++						gtk.main_iteration_do(True)
+ 					item2 = item + os.sep + item2
+ 					item_fullpath2 = os.path.abspath(item2)
+ 					if (not self.open_hidden_files and os.path.basename(item_fullpath2)[0] != '.') or self.open_hidden_files:
+@@ -4389,16 +4533,16 @@ class Base:
+ 							filelist.append(item2)
+ 							if self.verbose and print_found_msg:
+ 								self.images_found += 1
+-								print _("Found: %(fullpath)s [%(number)i]") % {'fullpath': item_fullpath2, 'number': self.images_found}
++								print (_("Found: %(fullpath)s [%(number)i]") % {'fullpath': item_fullpath2, 'number': self.images_found})
+ 						elif os.path.isdir(item_fullpath2) and self.recursive:
+ 							folderlist.append(item_fullpath2)
+ 					elif self.verbose:
+-						print _("Skipping: %s") % item_fullpath2
++						print (_("Skipping: %s") % item_fullpath2)
+ 			if len(self.image_list)>0 and update_window_title:
+ 				self.update_title()
+ 			# Sort the filelist and folderlist alphabetically:
+ 			if len(filelist) > 0:
+-				filelist.sort(locale.strcoll)
++				filelist.sort(key=functools.cmp_to_key(locale.strcoll))
+ 				for item2 in filelist:
+ 					if not item2 in self.image_list:
+ 						self.image_list.append(item2)
+@@ -4409,7 +4553,7 @@ class Base:
+ 							go_buttons_enabled = True
+ 			# Recurse into the folderlist:
+ 			if len(folderlist) > 0:
+-				folderlist.sort(locale.strcoll)
++				folderlist.sort(key=functools.cmp_to_key(locale.strcoll))
+ 				for item2 in folderlist:
+ 					if not self.stop_now:
+ 						self.expand_directory(item2, stop_when_second_image_found, go_buttons_enabled, update_window_title, print_found_msg)
+@@ -4422,7 +4566,7 @@ class Base:
+ 				uri = ''
+ 				if imgfile[:7] != 'file://':
+ 					uri = 'file://'
+-				uri = uri + urllib.pathname2url(os.path.abspath(imgfile))
++				uri = uri + urllib.request.pathname2url(os.path.abspath(imgfile))
+ 				gtk_recent_manager.add_item(uri)
+ 			except:
+ 				#Isnt currently functional on win32
+@@ -4432,14 +4576,16 @@ class Base:
+ 					raise
+ 
+ 	def valid_image(self, file):
+-		test = gtk.gdk.pixbuf_get_file_info(file)
++		test = GdkPixbuf.Pixbuf.get_file_info(file)
+ 		if test == None:
+ 			return False
+-		elif test[0]['name'] == "wbmp":
++		elif test[0] == None:
++			return False
++		elif test[0].get_name() == "wbmp":
+ 			# some regular files are thought to be wbmp for whatever reason,
+ 			# so let's check further.. :(
+ 			try:
+-				test2 = gtk.gdk.pixbuf_new_from_file(file)
++				test2 = GdkPixbuf.Pixbuf.new_from_file(file)
+ 				return True
+ 			except:
+ 				return False
+@@ -4455,14 +4601,14 @@ class Base:
+ 		else:
+ 			d, w, h, rws = imgfuncs.horiz(old_pix.get_pixels(), width, height, old_pix.get_rowstride(), old_pix.get_n_channels())
+ 		if d:
+-			new_pix = gtk.gdk.pixbuf_new_from_data(d, old_pix.get_colorspace(), old_pix.get_has_alpha(), old_pix.get_bits_per_sample(), w, h, rws)
++			new_pix = GdkPixbuf.Pixbuf.new_from_data(data=d, colorspace=old_pix.get_colorspace(), has_alpha=old_pix.get_has_alpha(), bits_per_sample=old_pix.get_bits_per_sample(), width=w, height=h, rowstride=rws)
+ 			return new_pix
+ 		return old_pix
+ 
+ 	def image_rotate(self, old_pix, full_angle):
+ 		width = old_pix.get_width()
+ 		height = old_pix.get_height()
+-		angle = full_angle - (int(full_angle) / 360) * 360
++		angle = full_angle - (int(full_angle) // 360) * 360
+ 		if angle:
+ 			d = None
+ 			if angle % 270 == 0:
+@@ -4472,7 +4618,7 @@ class Base:
+ 			elif angle % 90 == 0:
+ 				d, w, h, rws = imgfuncs.left(old_pix.get_pixels(), width, height, old_pix.get_rowstride(), old_pix.get_n_channels())
+ 			if d:
+-				new_pix = gtk.gdk.pixbuf_new_from_data(d, old_pix.get_colorspace(), old_pix.get_has_alpha(), old_pix.get_bits_per_sample(), w, h, rws)
++				new_pix = GdkPixbuf.Pixbuf.new_from_data(data=d, colorspace=old_pix.get_colorspace(), has_alpha=old_pix.get_has_alpha(), bits_per_sample=old_pix.get_bits_per_sample(), width=w, height=h, rowstride=rws)
+ 				return new_pix
+ 		return old_pix
+ 
+@@ -4485,16 +4631,16 @@ class Base:
+ 				self.update_title()
+ 				self.set_slideshow_sensitivities()
+ 				if not self.curr_slideshow_random:
+-					self.timer_delay = gobject.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_next_image, "ss")
++					self.timer_delay = GLib.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_next_image, "ss")
+ 				else:
+ 					self.reinitialize_randomlist()
+-					self.timer_delay = gobject.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_random_image, "ss")
++					self.timer_delay = GLib.timeout_add(int(self.curr_slideshow_delay*1000), self.goto_random_image, "ss")
+ 				self.ss_start.hide()
+ 				self.ss_stop.show()
+-				timer_screensaver = gobject.timeout_add(1000, self.disable_screensaver_in_slideshow_mode)
++				timer_screensaver = GLib.timeout_add(1000, self.disable_screensaver_in_slideshow_mode)
+ 			else:
+ 				self.slideshow_mode = False
+-				gobject.source_remove(self.timer_delay)
++				self.source_try_remove(self.timer_delay)
+ 				self.update_title()
+ 				self.set_slideshow_sensitivities()
+ 				self.set_zoom_sensitivities()
+@@ -4535,10 +4681,10 @@ class Base:
+ 				while gtk.events_pending():
+ 					gtk.main_iteration()
+ 
+-			ss_winheight = self.slideshow_window.allocation.height
+-			ss_win2width = self.slideshow_window2.allocation.width
+-			winheight = self.window.allocation.height
+-			winwidth = self.window.allocation.width
++			ss_winheight = self.slideshow_window.get_allocation().height
++			ss_win2width = self.slideshow_window2.get_allocation().width
++			winheight = self.window.get_allocation().height
++			winwidth = self.window.get_allocation().width
+ 			y = -3.0
+ 			self.controls_moving = True
+ 			while y < ss_winheight:
+@@ -4556,11 +4702,11 @@ class Base:
+ 
+ 			(xpos, ypos) = self.window.get_position()
+ 
+-			ss_winheight = self.slideshow_window.allocation.height
+-			ss_win2width = self.slideshow_window2.allocation.width
+-			winheight = self.window.allocation.height
+-			winwidth = self.window.allocation.width
+-			y = float(self.slideshow_window.allocation.height*1.0)
++			ss_winheight = self.slideshow_window.get_allocation().height
++			ss_win2width = self.slideshow_window2.get_allocation().width
++			winheight = self.window.get_allocation().height
++			winwidth = self.window.get_allocation().width
++			y = float(self.slideshow_window.get_allocation().height*1.0)
+ 			self.controls_moving = True
+ 			while y > -3:
+ 				self.slideshow_window.move(2+xpos, int(winheight-y-2))
+@@ -4574,14 +4720,14 @@ class Base:
+ 	def disable_screensaver_in_slideshow_mode(self):
+ 		if self.slideshow_mode and self.disable_screensaver:
+ 			test = os.spawnlp(os.P_WAIT, "/usr/bin/xscreensaver-command", "xscreensaver-command", "-deactivate")
+-			if test <> 127:
+-				timer_screensaver = gobject.timeout_add(1000, self.disable_screensaver_in_slideshow_mode)
++			if test != 127:
++				timer_screensaver = GLib.timeout_add(1000, self.disable_screensaver_in_slideshow_mode)
+ 
+ 	def main(self):
+ 		gtk.main()
+ 
+ if __name__ == "__main__":
+ 	base = Base()
+-	gtk.gdk.threads_enter()
++	gdk.threads_enter()
+ 	base.main()
+-	gtk.gdk.threads_leave()
++	gdk.threads_leave()
+diff -urp '--exclude=build' '--exclude=__pycache__' '--exclude=*~' '--exclude=*.py3' '--exclude=mo' mirage-0.9.5.2.py2/setup.py mirage-0.9.5.2.py3/setup.py
+--- mirage-0.9.5.2.py2/setup.py	2020-09-10 00:15:11.317964653 +0900
++++ mirage-0.9.5.2.py3/setup.py	2020-09-10 00:15:48.360874985 +0900
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python
++#!/usr/bin/env python3
+ 
+ # $HeadURL: http://svn.berlios.de/svnroot/repos/mirageiv/branches/mirage-0.9.x/setup.py $
+ # $Id: setup.py 337 2011-02-13 22:40:05Z fredricj $
+@@ -26,7 +26,7 @@ def removeall(path):
+ def rmgeneric(path, __func__):
+ 	try:
+ 		__func__(path)
+-	except OSError, (errno, strerror):
++	except OSError as errno:
+ 		pass
+ 
+ # Create mo files:
+@@ -37,7 +37,7 @@ for lang in ('it', 'de', 'pl', 'es', 'fr
+ 	mofile = "mo/" + lang + "/mirage.mo"
+ 	if not os.path.exists("mo/" + lang + "/"):
+ 		os.mkdir("mo/" + lang + "/")
+-	print "generating", mofile
++	print ("generating", mofile)
+ 	os.system("msgfmt %s -o %s" % (pofile, mofile))
+ 
+ setup(name='Mirage',
+diff -urp '--exclude=build' '--exclude=__pycache__' '--exclude=*~' '--exclude=*.py3' '--exclude=mo' mirage-0.9.5.2.py2/xmouse.c mirage-0.9.5.2.py3/xmouse.c
+--- mirage-0.9.5.2.py2/xmouse.c	2007-11-27 23:26:18.000000000 +0900
++++ mirage-0.9.5.2.py3/xmouse.c	2020-09-10 00:18:53.238427427 +0900
+@@ -35,12 +35,24 @@ PyObject* xmouse_geometry(PyObject* self
+     return ret;
+ }
+ 
+-PyMethodDef methods[] =
++PyMethodDef xmouse_methods[] =
+ {
+     {"geometry", xmouse_geometry, METH_VARARGS},
++    {NULL}
+ };
+ 
+-void initxmouse(void)
++/* Module initialization function */
++static struct PyModuleDef xmouse_module =
+ {
+-    Py_InitModule("xmouse", methods);
++    PyModuleDef_HEAD_INIT,
++    "xmouse", /* name of module */
++    NULL,          /* module documentation, may be NULL */
++    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
++    xmouse_methods
++};
++
++PyMODINIT_FUNC PyInit_xmouse(void)
++{
++    return PyModule_Create(&xmouse_module);
+ }
++
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/mirage.git/commitdiff/2880527d4403c22963889c5ea5ff2628e3aa350c




More information about the pld-cvs-commit mailing list