← easystroke

Port to gtk3

6905475c9522044d19825fb25a1587fb81dfad9c · Thomas Jaeger · Sep 7, 2012 03:24

+335 −385 · 15 files changed

  • Makefile +3 −8
  • actions.cc +19 −13
  • composite.cc +7 −15
  • composite.h +1 −1
  • dbus-server.cc +0 −90
  • dbus.xml +0 −13
  • easystroke.desktop.in +6 −1
  • gesture.h +1 −1
  • gui.glade +95 −30
  • main.cc +181 −202
  • main.h +1 −0
  • prefs.cc +2 −2
  • stats.cc +12 −5
  • win.cc +5 −3
  • win.h +2 −1
diff --git a/Makefile b/Makefile
index 40d0827..950dc13 100644
--- a/Makefile
+++ b/Makefile
@@ -22,10 +22,10 @@ DFLAGS   =
 OFLAGS   = -O2
 AOFLAGS  = -O3
 STROKEFLAGS  = -Wall -std=c99 $(DFLAGS)
-CXXFLAGS = -Wall $(DFLAGS) -DLOCALEDIR=\"$(LOCALEDIR)\" `pkg-config gtkmm-2.4 dbus-glib-1 --cflags`
+CXXFLAGS = -Wall $(DFLAGS) -DLOCALEDIR=\"$(LOCALEDIR)\" `pkg-config gtkmm-3.0 dbus-glib-1 --cflags`
 LDFLAGS  = $(DFLAGS)
 
-LIBS     = $(DFLAGS) -lboost_serialization -lX11 -lXext -lXi -lXfixes -lXtst `pkg-config gtkmm-2.4 dbus-glib-1 --libs`
+LIBS     = $(DFLAGS) -lboost_serialization -lX11 -lXext -lXi -lXfixes -lXtst `pkg-config gtkmm-3.0 dbus-glib-1 --libs`
 
 BINARY   = easystroke
 ICON     = easystroke.svg
@@ -39,7 +39,7 @@ POFILES  = $(wildcard po/*.po)
 MOFILES  = $(patsubst po/%.po,po/%/LC_MESSAGES/easystroke.mo,$(POFILES))
 MODIRS   = $(patsubst po/%.po,po/%,$(POFILES))
 DEPFILES = $(wildcard *.Po)
-GENFILES = gui.c desktop.c dbus-server.h po/POTFILES.in easystroke.desktop
+GENFILES = gui.c desktop.c po/POTFILES.in easystroke.desktop
 GZFILES  = $(wildcard *.gz)
 
 VERSION  = $(shell test -e debian/changelog && grep '(.*)' debian/changelog | sed 's/.*(//' | sed 's/).*//' | head -n1 || (test -e version && cat version || git describe))
@@ -83,11 +83,6 @@ desktop.c: easystroke.desktop
 	sed 's/Exec=easystroke/Exec=%s/' $< | sed 's/"/\\"/g' | sed 's/.*/&\\n\\/' >> $@
 	echo "\";" >> $@
 
-dbus-server.cc: dbus-server.h
-
-dbus-server.h: dbus.xml
-	dbus-binding-tool --prefix=server --mode=glib-server --output=$@ $<
-
 po/POTFILES.in: $(CCFILES) $(HFILES)
 	$(RM) $@
 	for f in `grep -El "\<_\(" $^`; do echo $$f >> $@; done
diff --git a/actions.cc b/actions.cc
index c8d8f8a..bc4145b 100644
--- a/actions.cc
+++ b/actions.cc
@@ -46,7 +46,7 @@ void TreeViewMulti::on_drag_begin(const Glib::RefPtr<Gdk::DragContext> &context)
 	pending = false;
 	if (get_selection()->count_selected_rows() <= 1)
 		return Gtk::TreeView::on_drag_begin(context);
-	Glib::RefPtr<Gdk::Pixbuf> pb = render_icon(Gtk::Stock::DND_MULTIPLE, Gtk::ICON_SIZE_DND);
+	Glib::RefPtr<Gdk::Pixbuf> pb = render_icon_pixbuf(Gtk::Stock::DND_MULTIPLE, Gtk::ICON_SIZE_DND);
 	context->set_icon(pb, pb->get_width(), pb->get_height());
 }
 
@@ -67,15 +67,18 @@ public:
 		WIDGET(Gtk::Label, label, _("Key combination..."));
 		label.set_alignment(0.0, 0.5);
 		add(label);
-		modify_bg(Gtk::STATE_NORMAL, widget.get_style()->get_bg(Gtk::STATE_SELECTED));
-		label.modify_fg(Gtk::STATE_NORMAL, widget.get_style()->get_fg(Gtk::STATE_SELECTED));
+		override_background_color(widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED), Gtk::STATE_FLAG_NORMAL);
+		label.override_color(widget.get_style_context()->get_color(Gtk::STATE_FLAG_SELECTED), Gtk::STATE_FLAG_NORMAL);
 		show_all();
 	}
 protected:
 
 	virtual void start_editing_vfunc(GdkEvent *event) {
 		add_modal_grab();
-		get_window()->keyboard_grab(false, gdk_event_get_time(event));
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+		gdk_keyboard_grab(get_window()->gobj(), false, gdk_event_get_time(event));
+#pragma GCC diagnostic pop
 		signal_key_press_event().connect(sigc::mem_fun(*this, &CellEditableAccel::on_key));
 	}
 
@@ -83,10 +86,10 @@ protected:
 		if (event->is_modifier)
 			return true;
 		switch (event->keyval) {
-			case GDK_Super_L:
-			case GDK_Super_R:
-			case GDK_Hyper_L:
-			case GDK_Hyper_R:
+			case GDK_KEY_Super_L:
+			case GDK_KEY_Super_R:
+			case GDK_KEY_Hyper_L:
+			case GDK_KEY_Hyper_R:
 				return true;
 		}
 		guint mods = event->state & gtk_accelerator_get_default_mod_mask();
@@ -101,12 +104,15 @@ protected:
 
 	virtual void on_editing_done() {
 		remove_modal_grab();
-		get_window()->keyboard_ungrab(CurrentTime);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+		gdk_keyboard_ungrab(CurrentTime);
+#pragma GCC diagnostic pop
 		Gtk::CellEditable::on_editing_done();
 	}
 };
 
-class CellEditableCombo : public Gtk::ComboBoxText, public Gtk::CellEditable {
+class CellEditableCombo : public Gtk::ComboBoxText {
 	CellRendererTextish *parent;
 	Glib::ustring path;
 public:
@@ -115,7 +121,7 @@ public:
 		parent(parent_), path(path_)
 	{
 		while (*items)
-			append_text(_(*(items++)));
+			append(_(*(items++)));
 	}
 protected:
 	virtual void on_changed() {
@@ -362,7 +368,7 @@ bool Actions::AppsStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path &des
 	if (expecting && expected != dest)
 		expecting = false;
 	if (!expecting) {
-		if (dest.get_depth() < 2 || dest.back() != 0)
+		if (gtk_tree_path_get_depth((GtkTreePath *)dest.gobj()) < 2 || dest.back() != 0)
 			return false;
 		expected = dest;
 		expected.up();
@@ -437,7 +443,7 @@ bool Actions::Store::row_draggable_vfunc(const Gtk::TreeModel::Path &path) const
 
 bool Actions::Store::row_drop_possible_vfunc(const Gtk::TreeModel::Path &dest, const Gtk::SelectionData &selection) const {
 	static bool ignore_next = false;
-	if (dest.get_depth() > 1) {
+	if (gtk_tree_path_get_depth((GtkTreePath *)dest.gobj()) > 1) {
 		ignore_next = true;
 		return false;
 	}
diff --git a/composite.cc b/composite.cc
index e043dab..ec70ad1 100644
--- a/composite.cc
+++ b/composite.cc
@@ -25,20 +25,19 @@ Popup::Popup(int x1, int y1, int x2, int y2) : Gtk::Window(Gtk::WINDOW_POPUP), r
 	if (!is_composited())
 		throw std::runtime_error(_("'composite' not available"));
 
-	Glib::RefPtr<Gdk::Colormap> colormap = get_screen()->get_rgba_colormap();
-	if (colormap)
-		set_colormap(colormap);
-	signal_expose_event().connect(sigc::mem_fun(*this, &Popup::on_expose));
+	Glib::RefPtr<Gdk::Visual> visual = get_screen()->get_rgba_visual();
+	gtk_widget_set_visual(Widget::gobj(), visual->gobj());
+	signal_draw().connect(sigc::mem_fun(*this, &Popup::on_draw));
 	realize();
 	move(x1, y1);
 	resize(x2-x1, y2-y1);
-	get_window()->input_shape_combine_region(Gdk::Region(), 0, 0);
+	get_window()->input_shape_combine_region(Cairo::Region::create(), 0, 0);
 	// tell compiz to leave this window the hell alone
 	get_window()->set_type_hint(Gdk::WINDOW_TYPE_HINT_DESKTOP);
 }
 
 void Popup::invalidate(int x1, int y1, int x2, int y2) {
-	if (is_mapped()) {
+	if (get_mapped()) {
 		Gdk::Rectangle inv(x1 - rect.get_x(), y1 - rect.get_y(), x2-x1, y2-y1);
 		get_window()->invalidate_rect(inv, false);
 	} else
@@ -109,17 +108,10 @@ void Popup::draw_line(Cairo::RefPtr<Cairo::Context> ctx) {
 
 }
 
-bool Popup::on_expose(GdkEventExpose* event) {
-	Cairo::RefPtr<Cairo::Context> ctx = get_window()->create_cairo_context();
+bool Popup::on_draw(const ::Cairo::RefPtr< ::Cairo::Context>& ctx) {
 	ctx->set_operator(Cairo::OPERATOR_SOURCE);
-
-	Gdk::Region region(event->region, true);
-	Gdk::Cairo::add_region_to_path(ctx, region);
-	ctx->clip();
-
-	Gdk::Cairo::add_region_to_path(ctx, region);
 	ctx->set_source_rgba(0.0, 0.0, 0.0, 0.0);
-	ctx->fill();
+	ctx->paint();
 
 	ctx->translate(-rect.get_x(), -rect.get_y());
 	draw_line(ctx);
diff --git a/composite.h b/composite.h
index 8d972e5..a9c4cdb 100644
--- a/composite.h
+++ b/composite.h
@@ -21,7 +21,7 @@
 #include <list>
 
 class Popup : public Gtk::Window {
-	bool on_expose(GdkEventExpose* event);
+	bool on_draw(const ::Cairo::RefPtr< ::Cairo::Context>& ctx);
 	void draw_line(Cairo::RefPtr<Cairo::Context> ctx);
 	Gdk::Rectangle rect;
 public:
diff --git a/dbus-server.cc b/dbus-server.cc
deleted file mode 100644
index 98c99f6..0000000
--- a/dbus-server.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Thomas Jaeger <ThJaeger@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include <dbus/dbus-protocol.h>
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-bindings.h>
-
-#include <stdio.h>
-#include "win.h"
-
-#define SERVER_OBJECT_TYPE (server_object_get_type())
-
-typedef struct _ServerObject {
-	GObject object;
-} ServerObject;
-
-typedef struct _ServerObjectClass {
-	GObjectClass object_class;
-} ServerObjectClass;
-
-void run_by_name(const char *str);
-
-static gboolean server_send(ServerObject *obj, const char *str, GError **error) {
-	run_by_name(str);
-	return TRUE;
-}
-
-extern Source<bool> disabled;
-static gboolean server_enable(ServerObject *obj, GError **error) {
-	disabled.set(!disabled.get());
-	return TRUE;
-}
-
-static gboolean server_about(ServerObject *obj, GError **error) {
-	win->show_about();
-	return TRUE;
-}
-
-extern void quit();
-static gboolean server_quit(ServerObject *obj, GError **error) {
-	quit();
-	return TRUE;
-}
-
-#include "dbus-server.h"
-
-static void server_object_class_init(ServerObjectClass *klass) {
-	dbus_g_object_type_install_info(G_TYPE_FROM_CLASS(klass), &dbus_glib_server_object_info);
-}
-
-static void server_object_init(ServerObject *obj) {}
-
-G_DEFINE_TYPE(ServerObject, server_object, G_TYPE_OBJECT);
-
-int start_dbus() {
-	DBusGConnection *connection;
-	DBusGProxy *proxy;
-	GError *error = NULL;
-	ServerObject *obj;
-	guint32 request_name_ret;
-
-	connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
-	if (!connection)
-		return false;
-
-	proxy = dbus_g_proxy_new_for_name(connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
-	if (!org_freedesktop_DBus_request_name(proxy, "org.easystroke", 0, &request_name_ret, &error))
-		return false;
-
-	if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
-		return -1;
-
-	g_object_unref(proxy);
-
-	obj =(ServerObject *)g_object_new(SERVER_OBJECT_TYPE, NULL);
-	dbus_g_connection_register_g_object(connection, "/org/easystroke", G_OBJECT(obj));
-	return true;
-}
diff --git a/dbus.xml b/dbus.xml
deleted file mode 100644
index 8055b4d..0000000
--- a/dbus.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<node name="/org/easystroke">
-	<interface name="org.easystroke">
-		<method name="send">
-			<arg type="s" name="action" direction="in" />
-		</method>
-		<method name="enable" />
-		<method name="about" />
-		<method name="quit" />
-	</interface>
-</node>
-
diff --git a/easystroke.desktop.in b/easystroke.desktop.in
index d8f3465..1257b05 100644
--- a/easystroke.desktop.in
+++ b/easystroke.desktop.in
@@ -6,6 +6,7 @@ Terminal=false
 Exec=easystroke
 Icon=easystroke
 Categories=GTK;Utility;Accessibility;
+Actions=About;Enable;Disable;Quit
 _Comment=Control your desktop using mouse gestures
 
 [Desktop Action About]
@@ -13,9 +14,13 @@ _Name=About
 Exec=easystroke about
 
 [Desktop Action Enable]
-_Name=Enable/Disable
+_Name=Enable
 Exec=easystroke enable
 
+[Desktop Action Disable]
+_Name=Disable
+Exec=easystroke disable
+
 [Desktop Action Quit]
 _Name=Quit
 Exec=easystroke quit
diff --git a/gesture.h b/gesture.h
index 10ab84a..accecdf 100644
--- a/gesture.h
+++ b/gesture.h
@@ -17,7 +17,7 @@
 #define __GESTURE_H__
 
 #include "stroke.h"
-#include <gdkmm/pixbuf.h>
+#include <gdkmm.h>
 #include <vector>
 #include <boost/shared_ptr.hpp>
 #include <boost/serialization/access.hpp>
diff --git a/gui.glade b/gui.glade
index c146fbd..704bca4 100644
--- a/gui.glade
+++ b/gui.glade
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkAboutDialog" id="aboutdialog">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -35,12 +34,13 @@ Jesus Vera (Spanish)
 Martín V. (Spanish)
 Van Diep Duong (Vietnamese)</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox4">
+      <object class="GtkBox" id="dialog-vbox4">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area4">
+          <object class="GtkButtonBox" id="dialog-action_area4">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
@@ -92,18 +92,19 @@ Van Diep Duong (Vietnamese)</property>
     <property name="message_type">warning</property>
     <property name="buttons">cancel</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox8">
+      <object class="GtkBox" id="dialog-vbox8">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area8">
+          <object class="GtkButtonBox" id="dialog-action_area8">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
             <child>
               <object class="GtkButton" id="button_delete_delete">
                 <property name="label">gtk-delete</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -139,12 +140,12 @@ Van Diep Duong (Vietnamese)</property>
     <property name="transient_for">main</property>
     <property name="buttons">ok</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox6">
+      <object class="GtkBox" id="dialog-vbox6">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area6">
+          <object class="GtkButtonBox" id="dialog-action_area6">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
@@ -166,18 +167,19 @@ Van Diep Duong (Vietnamese)</property>
     <property name="skip_taskbar_hint">True</property>
     <property name="transient_for">main</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox10">
+      <object class="GtkBox" id="dialog-vbox10">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area10">
+          <object class="GtkButtonBox" id="dialog-action_area10">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
             <child>
               <object class="GtkButton" id="button_record_cancel">
                 <property name="label">gtk-cancel</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -194,6 +196,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkButton" id="button_record_delete">
                 <property name="label" translatable="yes">_Delete Current</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -229,18 +232,20 @@ Van Diep Duong (Vietnamese)</property>
     <property name="skip_taskbar_hint">True</property>
     <property name="transient_for">main</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox9">
+      <object class="GtkBox" id="dialog-vbox9">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
         <property name="spacing">6</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area9">
+          <object class="GtkButtonBox" id="dialog-action_area9">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
             <child>
               <object class="GtkButton" id="select_cancel">
                 <property name="label">gtk-cancel</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -256,6 +261,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkButton" id="select_ok">
                 <property name="label">gtk-ok</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -271,6 +277,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkButton" id="select_default">
                 <property name="label" translatable="yes">_Default</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -301,10 +308,12 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkRadioButton" id="radio_timeout_default">
                 <property name="label" translatable="yes">Timeout</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
                 <property name="use_action_appearance">False</property>
+                <property name="xalign">0.5</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
               </object>
@@ -317,10 +326,12 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkRadioButton" id="radio_instant">
                 <property name="label" translatable="yes">Instant Gestures</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
                 <property name="use_action_appearance">False</property>
+                <property name="xalign">0.5</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
                 <property name="group">radio_timeout_default</property>
@@ -334,10 +345,12 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkRadioButton" id="radio_click_hold">
                 <property name="label" translatable="yes">Click &amp; Hold</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
                 <property name="use_action_appearance">False</property>
+                <property name="xalign">0.5</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
                 <property name="group">radio_timeout_default</property>
@@ -368,6 +381,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkToggleButton" id="toggle_control">
                 <property name="label" translatable="yes">_Control</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -382,6 +396,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkToggleButton" id="toggle_shift">
                 <property name="label" translatable="yes">_Shift</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -392,6 +407,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkToggleButton" id="toggle_alt">
                 <property name="label" translatable="yes">_Alt</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -406,6 +422,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkToggleButton" id="toggle_super">
                 <property name="label" translatable="yes">S_uper</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -422,6 +439,7 @@ Van Diep Duong (Vietnamese)</property>
             <child>
               <object class="GtkToggleButton" id="toggle_any">
                 <property name="label" translatable="yes">An_y Modifier</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -589,12 +607,13 @@ Van Diep Duong (Vietnamese)</property>
                           <object class="GtkScrolledWindow" id="scrolledwindow5">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="hscrollbar_policy">automatic</property>
-                            <property name="vscrollbar_policy">automatic</property>
                             <child>
                               <object class="GtkTreeView" id="treeview_apps">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="treeview-selection1"/>
+                                </child>
                               </object>
                             </child>
                           </object>
@@ -602,10 +621,12 @@ Van Diep Duong (Vietnamese)</property>
                         <child>
                           <object class="GtkCheckButton" id="check_show_deleted">
                             <property name="label" translatable="yes">Show deleted rows</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="use_action_appearance">False</property>
+                            <property name="xalign">0</property>
                             <property name="draw_indicator">True</property>
                           </object>
                           <packing>
@@ -624,6 +645,7 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkButton" id="button_add_app">
                                 <property name="label" translatable="yes">Add Application</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -639,6 +661,7 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkButton" id="button_remove_app">
                                 <property name="label" translatable="yes">Remove Application/Group</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -654,6 +677,7 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkButton" id="button_add_group">
                                 <property name="label" translatable="yes">Add Group</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -678,6 +702,7 @@ Van Diep Duong (Vietnamese)</property>
                         <child>
                           <object class="GtkButton" id="button_reset_actions">
                             <property name="label" translatable="yes">Reset Action(s)</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
@@ -713,8 +738,6 @@ Van Diep Duong (Vietnamese)</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
                     <child>
                       <placeholder/>
                     </child>
@@ -741,6 +764,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_record">
                     <property name="label" translatable="yes">_Record Stroke</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -758,6 +782,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_add_action">
                     <property name="label" translatable="yes">_Add Action</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -775,6 +800,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_delete_action">
                     <property name="label" translatable="yes">_Delete Action(s)</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -792,6 +818,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_hide1">
                     <property name="label" translatable="yes">_Hide</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -863,6 +890,7 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkButton" id="button_button">
                                 <property name="label" translatable="yes">_Gesture Button</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -911,6 +939,7 @@ Van Diep Duong (Vietnamese)</property>
                                     <child>
                                       <object class="GtkButton" id="button_add_extra">
                                         <property name="label">gtk-add</property>
+                                        <property name="use_action_appearance">False</property>
                                         <property name="visible">True</property>
                                         <property name="can_focus">True</property>
                                         <property name="receives_default">True</property>
@@ -926,6 +955,7 @@ Van Diep Duong (Vietnamese)</property>
                                     <child>
                                       <object class="GtkButton" id="button_edit_extra">
                                         <property name="label">gtk-edit</property>
+                                        <property name="use_action_appearance">False</property>
                                         <property name="visible">True</property>
                                         <property name="can_focus">True</property>
                                         <property name="receives_default">True</property>
@@ -941,6 +971,7 @@ Van Diep Duong (Vietnamese)</property>
                                     <child>
                                       <object class="GtkButton" id="button_remove_extra">
                                         <property name="label">gtk-remove</property>
+                                        <property name="use_action_appearance">False</property>
                                         <property name="visible">True</property>
                                         <property name="can_focus">True</property>
                                         <property name="receives_default">True</property>
@@ -964,8 +995,6 @@ Van Diep Duong (Vietnamese)</property>
                                   <object class="GtkScrolledWindow" id="scrolledwindow7">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
-                                    <property name="hscrollbar_policy">automatic</property>
-                                    <property name="vscrollbar_policy">automatic</property>
                                     <child>
                                       <object class="GtkTreeView" id="treeview_extra">
                                         <property name="height_request">120</property>
@@ -994,7 +1023,7 @@ Van Diep Duong (Vietnamese)</property>
                             </child>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">False</property>
                             <property name="position">1</property>
                           </packing>
@@ -1184,6 +1213,7 @@ Van Diep Duong (Vietnamese)</property>
                             </child>
                             <child>
                               <object class="GtkColorButton" id="button_color">
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -1234,10 +1264,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_feedback">
                                 <property name="label" translatable="yes">Show popups (</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1249,10 +1281,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_left_handed">
                                 <property name="label" translatable="yes">to the right of the cursor)</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1276,10 +1310,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_tray_icon">
                                 <property name="label" translatable="yes">Show tray icon</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1291,10 +1327,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_tray_feedback">
                                 <property name="label" translatable="yes">Show last gesture in tray</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1306,10 +1344,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_autostart">
                                 <property name="label" translatable="yes">Autostart easystroke</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1363,13 +1403,14 @@ Van Diep Duong (Vietnamese)</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="hscrollbar_policy">automatic</property>
-                        <property name="vscrollbar_policy">automatic</property>
                         <child>
                           <object class="GtkTreeView" id="treeview_exceptions">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection" id="treeview-selection3"/>
+                            </child>
                           </object>
                         </child>
                       </object>
@@ -1402,6 +1443,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_add_exception">
                     <property name="label" translatable="yes">_Add Exception</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -1419,6 +1461,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_remove_exception">
                     <property name="label" translatable="yes">_Remove Exception</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -1436,6 +1479,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_hide2">
                     <property name="label" translatable="yes">_Hide</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -1524,10 +1568,12 @@ Van Diep Duong (Vietnamese)</property>
                         <child>
                           <object class="GtkCheckButton" id="check_timeout_gestures">
                             <property name="label" translatable="yes">Timeout Gestures</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="use_action_appearance">False</property>
+                            <property name="xalign">0</property>
                             <property name="draw_indicator">True</property>
                           </object>
                           <packing>
@@ -1542,10 +1588,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_advanced_ignore">
                                 <property name="label" translatable="yes">Ignore strokes leading up to advanced gestures</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1557,6 +1605,7 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkLinkButton" id="linkbutton1">
                                 <property name="label" translatable="yes">(See Documentation)</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">True</property>
@@ -1586,10 +1635,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_advanced_popups">
                                 <property name="label" translatable="yes">Show popups on advanced gestures</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1601,10 +1652,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_osd">
                                 <property name="label" translatable="yes">Show OSD</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1615,7 +1668,7 @@ Van Diep Duong (Vietnamese)</property>
                             </child>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
                             <property name="position">3</property>
                           </packing>
@@ -1628,10 +1681,12 @@ Van Diep Duong (Vietnamese)</property>
                             <child>
                               <object class="GtkCheckButton" id="check_scroll_invert">
                                 <property name="label" translatable="yes">Invert Scroll Direction</property>
+                                <property name="use_action_appearance">False</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
                                 <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                               </object>
                               <packing>
@@ -1667,7 +1722,7 @@ Van Diep Duong (Vietnamese)</property>
                             </child>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
                             <property name="padding">6</property>
                             <property name="position">4</property>
@@ -1676,14 +1731,16 @@ Van Diep Duong (Vietnamese)</property>
                         <child>
                           <object class="GtkCheckButton" id="check_move_back">
                             <property name="label" translatable="yes">Move the cursor back to the original position after each gesture</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="use_action_appearance">False</property>
+                            <property name="xalign">0</property>
                             <property name="draw_indicator">True</property>
                           </object>
                           <packing>
-                            <property name="expand">True</property>
+                            <property name="expand">False</property>
                             <property name="fill">True</property>
                             <property name="position">5</property>
                           </packing>
@@ -1729,10 +1786,12 @@ Van Diep Duong (Vietnamese)</property>
                         <child>
                           <object class="GtkCheckButton" id="check_proximity">
                             <property name="label" translatable="yes">Stay in 'scroll' and 'ignore' mode as long as the pen is within range</property>
+                            <property name="use_action_appearance">False</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="use_action_appearance">False</property>
+                            <property name="xalign">0</property>
                             <property name="draw_indicator">True</property>
                           </object>
                           <packing>
@@ -1779,13 +1838,14 @@ Van Diep Duong (Vietnamese)</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="hscrollbar_policy">automatic</property>
-                        <property name="vscrollbar_policy">automatic</property>
                         <child>
                           <object class="GtkTreeView" id="treeview_devices">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection" id="treeview-selection4"/>
+                            </child>
                           </object>
                         </child>
                       </object>
@@ -1818,6 +1878,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_hide4">
                     <property name="label" translatable="yes">_Hide</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -1872,13 +1933,14 @@ Van Diep Duong (Vietnamese)</property>
                   <object class="GtkScrolledWindow" id="scrolledwindow2">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
                     <child>
                       <object class="GtkTreeView" id="treeview_recent">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="treeview-selection5"/>
+                        </child>
                       </object>
                     </child>
                   </object>
@@ -1891,13 +1953,14 @@ Van Diep Duong (Vietnamese)</property>
                   <object class="GtkScrolledWindow" id="scrolledwindow3">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
                     <child>
                       <object class="GtkTreeView" id="treeview_ranking">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="treeview-selection6"/>
+                        </child>
                       </object>
                     </child>
                   </object>
@@ -1923,6 +1986,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_hide3">
                     <property name="label" translatable="yes">_Hide</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
@@ -1940,6 +2004,7 @@ Van Diep Duong (Vietnamese)</property>
                 <child>
                   <object class="GtkButton" id="button_matrix">
                     <property name="label" translatable="yes">_Matrix</property>
+                    <property name="use_action_appearance">False</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
diff --git a/main.cc b/main.cc
index a03e5ab..0bb2617 100644
--- a/main.cc
+++ b/main.cc
@@ -59,12 +59,6 @@ Grabber::XiDevice *current_dev = 0;
 std::set<guint> xinput_pressed; // TODO get rid of
 guint modifiers;
 
-static bool show_gui = false;
-static bool no_dbus = false;
-
-static int argc;
-static char **argv;
-
 static Window ping_window = 0;
 static boost::shared_ptr<Trace> trace;
 static std::map<guint, guint> core_inv_map;
@@ -192,8 +186,8 @@ public:
 		set_border_width(15);
 		WIDGET(Gtk::Label, label, "<big><b>" + txt + "</b></big>");
 		label.set_use_markup();
-		label.modify_fg(Gtk::STATE_NORMAL, Gdk::Color("White"));
-		modify_bg(Gtk::STATE_NORMAL, Gdk::Color("RoyalBlue3"));
+		label.override_color(Gdk::RGBA("White"), Gtk::STATE_FLAG_NORMAL);
+		override_background_color(Gdk::RGBA("RoyalBlue3"), Gtk::STATE_FLAG_NORMAL);
 		set_opacity(0.75);
 		add(label);
 		label.show();
@@ -201,7 +195,7 @@ public:
 		get_size(w,h);
 		do_move();
 		show();
-		get_window()->input_shape_combine_region(Gdk::Region(), 0, 0);
+		get_window()->input_shape_combine_region(Cairo::Region::create(), 0, 0);
 	}
 	static void do_move() {
 		int left = gdk_screen_width() - 10;
@@ -325,12 +319,8 @@ static int xErrorHandler(Display *dpy2, XErrorEvent *e) {
 static int xIOErrorHandler(Display *dpy2) {
 	if (dpy != dpy2)
 		return oldIOHandler(dpy2);
-	printf(_("Fatal Error: Connection to X server lost, restarting...\n"));
-	char *args[argc+1];
-	for (int i = 0; i<argc; i++)
-		args[i] = argv[i];
-	args[argc] = NULL;
-	execv(argv[0], args);
+	printf("Fatal Error: Connection to X server lost\n");
+	quit();
 	return 0;
 }
 
@@ -1050,11 +1040,7 @@ static void do_run_by_name(RAction act) {
 	act->run();
 }
 
-void run_by_name(const char *str) {
-	if (!strcmp(str, "")) {
-		win->show_hide();
-		return;
-	}
+static void run_by_name(const char *str, const Glib::RefPtr<Gio::ApplicationCommandLine> &cmd_line) {
 	for (ActionDB::const_iterator i = actions.begin(); i != actions.end(); i++) {
 		if (i->second.name == std::string(str)) {
 			if (i->second.action)
@@ -1062,7 +1048,10 @@ void run_by_name(const char *str) {
 			return;
 		}
 	}
-	printf(_("Warning: No action \"%s\" defined\n"), str);
+	char *msg;
+	asprintf(&msg, _("Warning: No action \"%s\" defined\n"), str);
+	cmd_line->print(msg);
+	free(msg);
 }
 
 void icon_warning() {
@@ -1091,27 +1080,28 @@ void quit() {
 	queue(sigc::ptr_fun(&Gtk::Main::quit));
 }
 
-static void quit(int) { quit(); }
-
-class Main {
-	std::string parse_args_and_init_gtk();
-	void create_config_dir();
-	char* next_event();
-	void usage(char *me, bool good);
+class App : public Gtk::Application {
+public:
+	App(int& argc, char**& argv, const Glib::ustring& application_id, Gio::ApplicationFlags flags=Gio::APPLICATION_FLAGS_NONE) :
+		Gtk::Application(argc, argv, application_id, flags), remote(false) {}
+	~App();
+private:
+	void on_activate();
+	virtual bool local_command_line_vfunc (char**& arguments, int& exit_status);
+	int on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &);
+
+	void usage(const char *me);
 	void version();
 
-	std::string display;
-	Gtk::Main *kit;
-public:
-	Main();
-	void run();
+	void create_config_dir();
 	bool handle(Glib::IOCondition);
 	void handle_enter_leave(XEvent &ev);
 	void handle_event(XEvent &ev);
 	void handle_xi2_event(XIDeviceEvent *event);
 	void handle_raw_motion(XIRawEvent *event);
 	void report_xi2_event(XIDeviceEvent *event, const char *type);
-	~Main();
+
+	bool remote;
 };
 
 class ReloadTrace : public Timeout {
@@ -1125,76 +1115,139 @@ class ReloadTrace : public Timeout {
 
 static void schedule_reload_trace() { reload_trace.set_timeout(1000); }
 
-static void xdg_open(const Glib::ustring str) {
-	if (!fork()) {
-		execlp("xdg-open", "xdg-open", str.c_str(), NULL);
-		exit(EXIT_FAILURE);
+extern const char *gui_buffer;
+
+bool App::local_command_line_vfunc (char**& arg, int& exit_status) {
+	int i = 1;
+	while (arg[i] && arg[i][0] == '-') {
+		if (arg[i][1] == '-') {
+			if (!strcmp(arg[i], "--experimental")) {
+				experimental = true;
+			} else if (!strcmp(arg[i], "--verbose")) {
+				verbosity++;
+			} else if (!strcmp(arg[i], "--help")) {
+				usage(arg[0]);
+				exit_status = EXIT_SUCCESS;
+				return true;
+			} else if (!strcmp(arg[i], "--version")) {
+				version();
+				exit_status = EXIT_SUCCESS;
+				return true;
+			} else if (!strcmp(arg[i], "--config-dir")) {
+				if (!arg[++i]) {
+					printf("Error: Option --config-dir requires an argument.\n");
+					exit_status = EXIT_FAILURE;
+					return true;
+				}
+				config_dir = arg[i];
+			} else {
+				printf("Error: Unknown option %s\n", arg[i]);
+				exit_status = EXIT_FAILURE;
+				return true;
+			}
+		} else {
+			for (int j = 1; arg[i][j]; j++)
+				switch (arg[i][j]) {
+					case 'c':
+						if (arg[i][j+1] || !arg[i+1]) {
+							printf("Error: Option -c requires an argument.\n");
+							exit_status = EXIT_FAILURE;
+							return true;
+						}
+						config_dir = arg[++i];
+						break;
+					case 'e':
+						experimental = true;
+						break;
+					case 'v':
+						verbosity++;
+						break;
+					case 'h':
+						usage(arg[0]);
+						exit_status = EXIT_SUCCESS;
+						return true;
+					default:
+						printf("Error: Unknown option -%c\n", arg[i][j]);
+						exit_status = EXIT_FAILURE;
+						return true;
+				}
+		}
+		i++;
 	}
-}
 
-static void link_button_hook(Gtk::LinkButton *, const Glib::ustring& uri) { xdg_open(uri); }
-static void about_dialog_hook(Gtk::AboutDialog &, const Glib::ustring& url) { xdg_open(url); }
+	if (i > 1) {
+		for (int j = 1; j < i; j++) {
+			g_free(arg[j]);
+			arg[j] = 0;
+		}
+		for (int j = 0; arg[j+i]; j++) {
+			arg[j+1] = arg[j+i];
+			arg[j+i] = 0;
+		}
+	}
 
-// dbus-send --type=method_call --dest=org.easystroke /org/easystroke org.easystroke.send string:"foo"
-static void send_dbus(bool action, const char *str) {
-	GError *error = 0;
-	DBusGConnection *bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
-	if (!bus) {
-		printf(_("Error initializing D-BUS\n"));
-		exit(EXIT_FAILURE);
+	if (!register_application()) {
+		printf("Failed to register the application\n");
+		exit_status = EXIT_FAILURE;
+		return true;
 	}
-	DBusGProxy *proxy = dbus_g_proxy_new_for_name(bus, "org.easystroke", "/org/easystroke", "org.easystroke");
-	if (action)
-		dbus_g_proxy_call_no_reply(proxy, "send", G_TYPE_STRING, str, G_TYPE_INVALID);
-	else
-		dbus_g_proxy_call_no_reply(proxy, str, G_TYPE_INVALID);
+	activate();
+	return false;
 }
 
-int start_dbus();
 
-Main::Main() : kit(0) {
+int App::on_command_line(const Glib::RefPtr<Gio::ApplicationCommandLine> &command_line) {
+	int argc;
+	char **arg = command_line->get_arguments(argc);
+	for (int i = 1; arg[i]; i++)
+		if (!strcmp(arg[i], "send")) {
+			if (!arg[++i])
+				printf("Warning: Send requires an argument\n");
+			else
+				run_by_name(arg[i], command_line);
+		} else if (!strcmp(arg[i], "show")) {
+			win->show();
+		} else if (!strcmp(arg[i], "hide")) {
+			win->hide();
+		} else if (!strcmp(arg[i], "disable")) {
+			disabled.set(true);
+		} else if (!strcmp(arg[i], "enable")) {
+			disabled.set(false);
+		} else if (!strcmp(arg[i], "about")) {
+			win->show_about();
+		} else if (!strcmp(arg[i], "quit")) {
+			quit();
+		} else {
+			char *msg;
+			asprintf(&msg, "Warning: Unknown command \"%s\".\n", arg[i]);
+			command_line->print(msg);
+			free(msg);
+		}
+	if (!arg[1] && remote)
+		win->show_hide();
+	remote = true;
+	return true;
+}
+
+void App::on_activate() {
+	if (win)
+		return;
+
 	bindtextdomain("easystroke", is_dir("po") ? "po" : LOCALEDIR);
 	bind_textdomain_codeset("easystroke", "UTF-8");
 	textdomain("easystroke");
-	if (0) {
-		RStroke trefoil = Stroke::trefoil();
-		trefoil->draw_svg("easystroke.svg");
-		exit(EXIT_SUCCESS);
-	}
-	if (argc > 1 && !strcmp(argv[1], "send")) {
-		if (argc == 2)
-			usage(argv[0], false);
-		gtk_init(&argc, &argv);
-		send_dbus(true, argv[2]);
-		exit(EXIT_SUCCESS);
-	}
 
-	if (argc > 1 && (!strcmp(argv[1], "enable") || !strcmp(argv[1], "about") || !strcmp(argv[1], "quit"))) {
-		gtk_init(&argc, &argv);
-		send_dbus(false, argv[1]);
-		exit(EXIT_SUCCESS);
-	}
+	oldHandler = XSetErrorHandler(xErrorHandler);
+	oldIOHandler = XSetIOErrorHandler(xIOErrorHandler);
 
-	display = parse_args_and_init_gtk();
 	create_config_dir();
 	unsetenv("DESKTOP_AUTOSTART_ID");
-
-	signal(SIGINT, &quit);
-	signal(SIGCHLD, SIG_IGN);
-
-	Gtk::LinkButton::set_uri_hook(sigc::ptr_fun(&link_button_hook));
-	Gtk::AboutDialog::set_url_hook(sigc::ptr_fun(&about_dialog_hook));
-
-	dpy = XOpenDisplay(display.c_str());
+	dpy = XOpenDisplay(NULL);
 	if (!dpy) {
 		printf(_("Couldn't open display.\n"));
 		exit(EXIT_FAILURE);
 	}
-	if (!no_dbus && start_dbus() < 0) {
-		printf(_("Easystroke is already running, showing configuration window instead.\n"));
-		send_dbus(true, "");
-		exit(EXIT_SUCCESS);
-	}
+
 	ROOT = DefaultRootWindow(dpy);
 
 	ping_window = XCreateSimpleWindow(dpy, ROOT, 0, 0, 1, 1, 0, 0, 0);
@@ -1220,13 +1273,8 @@ Main::Main() : kit(0) {
 	handler->init();
 	XTestGrabControl(dpy, True);
 
-}
-
-extern const char *gui_buffer;
-
-void Main::run() {
 	Glib::RefPtr<Glib::IOSource> io = Glib::IOSource::create(ConnectionNumber(dpy), Glib::IO_IN);
-	io->connect(sigc::mem_fun(*this, &Main::handle));
+	io->connect(sigc::mem_fun(*this, &App::handle));
 	io->attach();
 	try {
 		widgets = Gtk::Builder::create_from_string(gui_buffer);
@@ -1235,116 +1283,45 @@ void Main::run() {
 		exit(EXIT_FAILURE);
 	}
 	win = new Win;
-	if (show_gui || !actions.get_root()->size_rec())
+	add_window(win->get_window());
+	if (!actions.get_root()->size_rec())
 		win->get_window().show();
-	Gtk::Main::run();
-	delete win;
+	hold();
 }
 
-void Main::usage(char *me, bool good) {
+void App::usage(const char *me) {
 	printf("The full easystroke documentation is available at the following address:\n");
 	printf("\n");
 	printf("http://easystroke.wiki.sourceforge.net/Documentation#content\n");
 	printf("\n");
-	printf("Usage: %s [OPTION]...\n", me);
-	printf("or:    %s send <action_name>\n", me);
-	printf("       %s enable\n", me);
-	printf("       %s about\n", me);
-	printf("       %s quit\n", me);
+	printf("Usage: %s [OPTION]... [COMMAND]...\n", me);
+	printf("\n");
+	printf("Commands:\n");
+	printf("  send <action_name>     Execute action <action_name>\n");
+	printf("  show                   Show configuration window\n");
+	printf("  hide                   Hide configuration window\n");
+	printf("  disable                Disable easystroke\n");
+	printf("  enable                 Enable easystroke\n");
+	printf("  about                  Show about dialog\n");
+	printf("  quit                   Quit easystroke\n");
 	printf("\n");
 	printf("Options:\n");
-	printf("  -c, --config-dir       Directory for config files\n");
-	printf("      --display          X Server to contact\n");
-	printf("  -D  --no-dbus          Don't try to register as a DBus service\n");
+	printf("  -c, --config-dir <dir> Directory for config files\n");
 	printf("  -e  --experimental     Start in experimental mode\n");
-	printf("  -g, --show-gui         Show the configuration dialog on startup\n");
-	printf("  -x  --disable          Start disabled\n");
 	printf("  -v, --verbose          Increase verbosity level\n");
 	printf("  -h, --help             Display this help and exit\n");
 	printf("      --version          Output version information and exit\n");
-	exit(good ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 extern const char *version_string;
-void Main::version() {
+void App::version() {
 	printf("easystroke %s\n", version_string);
 	printf("\n");
 	printf("Written by Thomas Jaeger <ThJaeger@gmail.com>.\n");
 	exit(EXIT_SUCCESS);
 }
 
-std::string Main::parse_args_and_init_gtk() {
-	static struct option long_opts1[] = {
-		{"display",1,0,'d'},
-		{"help",0,0,'h'},
-		{"version",0,0,'V'},
-		{"show-gui",0,0,'g'},
-		{0,0,0,0}
-	};
-	static struct option long_opts2[] = {
-		{"config-dir",1,0,'c'},
-		{"display",1,0,'d'},
-		{"experimental",0,0,'e'},
-		{"show-gui",0,0,'g'},
-		{"verbose",0,0,'v'},
-		{"no-dbus",0,0,'D'},
-		{"disabled",0,0,'x'},
-		{0,0,0,0}
-	};
-	std::string display;
-	int opt;
-	// parse --display here, before Gtk::Main(...) takes it away from us
-	opterr = 0;
-	while ((opt = getopt_long(argc, argv, "gh", long_opts1, 0)) != -1)
-		switch (opt) {
-			case 'd':
-				display = optarg;
-				break;
-			case 'g':
-				show_gui = true;
-				break;
-			case 'h':
-				usage(argv[0], true);
-				break;
-			case 'V':
-				version();
-				break;
-		}
-	optind = 1;
-	opterr = 1;
-	kit = new Gtk::Main(argc, argv);
-	oldHandler = XSetErrorHandler(xErrorHandler);
-	oldIOHandler = XSetIOErrorHandler(xIOErrorHandler);
-
-	while ((opt = getopt_long(argc, argv, "c:egvDx", long_opts2, 0)) != -1) {
-		switch (opt) {
-			case 'c':
-				config_dir = optarg;
-				break;
-			case 'e':
-				experimental = true;
-				break;
-			case 'v':
-				verbosity++;
-				break;
-			case 'D':
-				no_dbus = true;
-				break;
-			case 'x':
-				disabled.set(true);
-				break;
-			case 'd':
-			case 'n':
-			case 'g':
-				break;
-			default:
-				usage(argv[0], false);
-		}
-	}
-	return display;
-}
-
-void Main::create_config_dir() {
+void App::create_config_dir() {
 	if (config_dir == "") {
 		config_dir = getenv("HOME");
 		config_dir += "/.easystroke";
@@ -1372,7 +1349,7 @@ void Main::create_config_dir() {
 
 extern Window get_app_window(Window w);
 
-void Main::handle_enter_leave(XEvent &ev) {
+void App::handle_enter_leave(XEvent &ev) {
 	if (ev.xcrossing.mode == NotifyGrab)
 		return;
 	if (ev.xcrossing.detail == NotifyInferior)
@@ -1386,7 +1363,7 @@ void Main::handle_enter_leave(XEvent &ev) {
 }
 
 #define H (handler->top())
-void Main::handle_event(XEvent &ev) {
+void App::handle_event(XEvent &ev) {
 
 	switch(ev.type) {
 	case EnterNotify:
@@ -1450,7 +1427,7 @@ static void print_coordinates(XIValuatorState *valuators, double *values) {
 	}
 }
 
-void Main::report_xi2_event(XIDeviceEvent *event, const char *type) {
+void App::report_xi2_event(XIDeviceEvent *event, const char *type) {
 	printf("%s (XI2): ", type);
 	if (event->detail)
 		printf("%d ", event->detail);
@@ -1459,7 +1436,7 @@ void Main::report_xi2_event(XIDeviceEvent *event, const char *type) {
 	printf(") at t = %ld\n", event->time);
 }
 
-void Main::handle_xi2_event(XIDeviceEvent *event) {
+void App::handle_xi2_event(XIDeviceEvent *event) {
 	switch (event->evtype) {
 		case XI_ButtonPress:
 			if (verbosity >= 3)
@@ -1513,7 +1490,7 @@ void Main::handle_xi2_event(XIDeviceEvent *event) {
 	}
 }
 
-void Main::handle_raw_motion(XIRawEvent *event) {
+void App::handle_raw_motion(XIRawEvent *event) {
 	if (!current_dev || current_dev->dev != event->deviceid)
 		return;
 	double x = 0.0, y = 0.0;
@@ -1542,7 +1519,7 @@ void Main::handle_raw_motion(XIRawEvent *event) {
 
 #undef H
 
-bool Main::handle(Glib::IOCondition) {
+bool App::handle(Glib::IOCondition) {
 	while (XPending(dpy)) {
 		try {
 			XEvent ev;
@@ -1557,24 +1534,26 @@ bool Main::handle(Glib::IOCondition) {
 	return true;
 }
 
-Main::~Main() {
-	trace->end();
-	trace.reset();
-	delete grabber;
-	delete kit;
-	XCloseDisplay(dpy);
-	prefs.execute_now();
-	action_watcher->execute_now();
+App::~App() {
+	if (win) {
+		delete win;
+		trace->end();
+		trace.reset();
+		delete grabber;
+		XCloseDisplay(dpy);
+		prefs.execute_now();
+		action_watcher->execute_now();
+	}
 }
 
-int main(int argc_, char **argv_) {
-	argc = argc_;
-	argv = argv_;
-	Main mn;
-	mn.run();
-	if (verbosity >= 2)
-		printf("Exiting...\n");
-	return EXIT_SUCCESS;
+int main(int argc, char **argv) {
+	if (0) {
+		RStroke trefoil = Stroke::trefoil();
+		trefoil->draw_svg("easystroke.svg");
+		exit(EXIT_SUCCESS);
+	}
+	App app(argc, argv, "org.easystroke.easystroke", Gio::APPLICATION_HANDLES_COMMAND_LINE);
+	return app.run(argc, argv);
 }
 
 std::string select_window() {
diff --git a/main.h b/main.h
index 8fe688b..cbc121d 100644
--- a/main.h
+++ b/main.h
@@ -21,6 +21,7 @@
 
 bool is_file(std::string filename);
 bool is_dir(std::string dirname);
+void quit();
 
 extern std::string config_dir;
 extern const char *prefs_versions[];
diff --git a/prefs.cc b/prefs.cc
index efbf091..f246aa5 100644
--- a/prefs.cc
+++ b/prefs.cc
@@ -116,7 +116,7 @@ public:
 		combo = Gtk::manage(new Gtk::ComboBoxText);
 		parent->add(*combo);
 		for (const Info *i = info; i->name; i++)
-			combo->append_text(_(i->name));
+			combo->append(_(i->name));
 		notify();
 		combo->signal_changed().connect(sigc::mem_fun(*this, &Combo::on_changed));
 		combo->show();
@@ -468,7 +468,7 @@ SelectButton::SelectButton(ButtonInfo bi, bool def, bool any) {
 		select_button = Gtk::manage(new Gtk::ComboBoxText);
 		box_button->add(*select_button);
 		for (int i = 1; i <= 12; i++)
-			select_button->append_text(Glib::ustring::compose(_("Button %1"), i));
+			select_button->append(Glib::ustring::compose(_("Button %1"), i));
 		select_button->show();
 	}
 	select_button->set_active(bi.button-1);
diff --git a/stats.cc b/stats.cc
index e83517d..8e56c0c 100644
--- a/stats.cc
+++ b/stats.cc
@@ -63,10 +63,14 @@ public:
 		if (s) {
 			icon.reset(new Gtk::Window(Gtk::WINDOW_POPUP));
 			icon->set_type_hint(Gdk::WINDOW_TYPE_HINT_TOOLTIP);
-			icon->set_name("gtk-tooltip");
+			icon->get_style_context()->add_class(GTK_STYLE_CLASS_TOOLTIP);
+			Glib::RefPtr<Gdk::Visual> visual = icon->get_screen()->get_rgba_visual();
+			gtk_widget_set_visual((GtkWidget *)icon->gobj(), visual->gobj());
+
 			WIDGET(Gtk::Image, image, s->draw(STROKE_SIZE));
 			icon->set_accept_focus(false);
 			icon->add(image);
+			image.set_padding(2,2);
 			image.show();
 			icon->get_size(w,h);
 			icon->move(x - w/2, y - h/2);
@@ -76,22 +80,25 @@ public:
 		if (t != "") {
 			text.reset(new Gtk::Window(Gtk::WINDOW_POPUP));
 			text->set_type_hint(Gdk::WINDOW_TYPE_HINT_TOOLTIP);
-			text->set_name("gtk-tooltip");
+			text->get_style_context()->add_class(GTK_STYLE_CLASS_TOOLTIP);
+			Glib::RefPtr<Gdk::Visual> visual = text->get_screen()->get_rgba_visual();
+			gtk_widget_set_visual((GtkWidget *)text->gobj(), visual->gobj());
+
 			text->set_accept_focus(false);
-			text->set_border_width(2);
 			WIDGET(Gtk::Label, label, t);
 			text->add(label);
+			label.set_padding(4,4);
 			label.show();
 			text->get_size(w,h);
 			text->move(x - w/2, y + h/2);
 		}
 		if (text) {
 			text->show();
-			text->get_window()->input_shape_combine_region(Gdk::Region(), 0, 0);
+			text->get_window()->input_shape_combine_region(Cairo::Region::create(), 0, 0);
 		}
 		if (icon) {
 			icon->show();
-			icon->get_window()->input_shape_combine_region(Gdk::Region(), 0, 0);
+			icon->get_window()->input_shape_combine_region(Cairo::Region::create(), 0, 0);
 		}
 	}
 };
diff --git a/win.cc b/win.cc
index 4190a40..086451f 100644
--- a/win.cc
+++ b/win.cc
@@ -164,8 +164,6 @@ public:
 	}
 };
 
-extern void quit();
-
 Win::Win() : actions(new Actions), prefs_tab(new Prefs), stats(new Stats) {
 	show_hide_icon();
 	prefs.tray_icon.connect(new Notifier(sigc::mem_fun(*this, &Win::show_hide_icon)));
@@ -248,12 +246,16 @@ void Win::show_about() {
 }
 
 void Win::show_hide() {
-	if (win->is_mapped())
+	if (win->get_mapped())
 		win->hide();
 	else
 		win->show();
 }
 
+void Win::show() {
+	win->show();
+}
+
 void Win::hide() {
 	win->hide();
 }
diff --git a/win.h b/win.h
index 67730e8..ada98d0 100644
--- a/win.h
+++ b/win.h
@@ -57,10 +57,11 @@ public:
 	boost::shared_ptr<Actions> actions;
 	boost::shared_ptr<Prefs> prefs_tab;
 	boost::shared_ptr<Stats> stats;
+	void show();
+	void hide();
 	void show_hide();
 	void set_icon(RStroke stroke, bool invert);
 	void show_about();
-	void hide();
 private:
 	bool on_icon_size_changed(int);
 	virtual void timeout();