[tasque] Refactor single instance logic for Linux
- From: Antonius Riha <antoniusri src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tasque] Refactor single instance logic for Linux
- Date: Fri, 30 Nov 2012 16:13:49 +0000 (UTC)
commit d001c7c5040e04aad44a868a880add31c7603a47
Author: Antonius Riha <antoniusriha gmail com>
Date: Fri Nov 30 16:44:31 2012 +0100
Refactor single instance logic for Linux
* moved to GtkApplication
* INativeApplication inherits from IDisposable now
* Logger has been moved to libtasque
* RemoteControlProxy dropped and incorporated in RemoteControl
src/Gtk.Tasque/Application.cs | 29 +---------------
src/Gtk.Tasque/Gtk.Tasque.csproj | 2 -
src/Gtk.Tasque/GtkApplication.cs | 57 +++++++++++++++++++++++++++++-
src/Gtk.Tasque/RemoteControl.cs | 35 ++++++++++++++++++-
src/Gtk.Tasque/RemoteControlProxy.cs | 36 -------------------
src/libtasque/INativeApplication.cs | 2 +-
src/{Gtk.Tasque => libtasque}/Logger.cs | 0
src/libtasque/NativeApplication.cs | 37 +++++++++++++++++++-
src/libtasque/libtasque.csproj | 1 +
9 files changed, 127 insertions(+), 72 deletions(-)
---
diff --git a/src/Gtk.Tasque/Application.cs b/src/Gtk.Tasque/Application.cs
index 5f00b91..14b3afc 100644
--- a/src/Gtk.Tasque/Application.cs
+++ b/src/Gtk.Tasque/Application.cs
@@ -53,9 +53,7 @@ namespace Tasque
private static System.Object locker = new System.Object();
private bool initialized;
private INativeApplication nativeApp;
-#if !WIN && !OSX
- private RemoteControl remoteControl;
-#endif
+
private Gdk.Pixbuf normalPixBuf;
private Gtk.Image trayImage;
private GtkTray trayIcon;
@@ -145,31 +143,6 @@ namespace Tasque
preferences = new Preferences (nativeApp.ConfDir);
-#if !WIN && !OSX
- // Register Tasque RemoteControl
- try {
- remoteControl = RemoteControlProxy.Register ();
- if (remoteControl != null) {
- Logger.Debug ("Tasque remote control active.");
- } else {
- // If Tasque is already running, open the tasks window
- // so the user gets some sort of feedback when they
- // attempt to run Tasque again.
- RemoteControl remote = null;
- try {
- remote = RemoteControlProxy.GetInstance ();
- remote.ShowTasks ();
- } catch {}
-
- Logger.Debug ("Tasque is already running. Exiting...");
- System.Environment.Exit (0);
- }
- } catch (Exception e) {
- Logger.Debug ("Tasque remote control disabled (DBus exception): {0}",
- e.Message);
- }
-#endif
-
string potentialBackendClassName = null;
for (int i = 0; i < args.Length; i++) {
diff --git a/src/Gtk.Tasque/Gtk.Tasque.csproj b/src/Gtk.Tasque/Gtk.Tasque.csproj
index ea3135c..0a43d44 100644
--- a/src/Gtk.Tasque/Gtk.Tasque.csproj
+++ b/src/Gtk.Tasque/Gtk.Tasque.csproj
@@ -92,7 +92,6 @@
<Compile Include="CompletedTaskGroupModel.cs" />
<Compile Include="DateButton.cs" />
<Compile Include="GtkApplication.cs" />
- <Compile Include="Logger.cs" />
<Compile Include="NoteDialog.cs" />
<Compile Include="NoteWidget.cs" />
<None Include="OSXApplication.cs" />
@@ -112,7 +111,6 @@
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'LinuxDebug' Or '$(Configuration)' == 'LinuxRelease' ">
<Compile Include="RemoteControl.cs" />
- <Compile Include="RemoteControlProxy.cs" />
</ItemGroup>
<ItemGroup>
<Substitute Include="Defines.cs.in" />
diff --git a/src/Gtk.Tasque/GtkApplication.cs b/src/Gtk.Tasque/GtkApplication.cs
index 7c9cd16..c7c6681 100644
--- a/src/Gtk.Tasque/GtkApplication.cs
+++ b/src/Gtk.Tasque/GtkApplication.cs
@@ -31,8 +31,6 @@ namespace Tasque
{
public class GtkApplication : NativeApplication
{
- private string confDir;
-
public GtkApplication ()
{
confDir = Path.Combine (
@@ -48,6 +46,8 @@ namespace Tasque
Mono.Unix.Catalog.Init ("tasque", Defines.LocaleDir);
Gtk.Application.Init ();
+
+ base.Initialize (args);
// add package icon path to default icon theme search paths
Gtk.IconTheme.Default.PrependSearchPath (Defines.IconsDir);
@@ -82,5 +82,58 @@ namespace Tasque
Logger.Error ("Error opening url [{0}]:\n{1}", url, e.ToString ());
}
}
+
+ protected override bool IsRemoteInstanceRunning ()
+ {
+#if LINUX
+ // Register Tasque RemoteControl
+ try {
+ remoteInstance = RemoteControl.Register ();
+ if (remoteInstance != null) {
+ remoteInstance.RemoteInstanceKnocked = HandleRemoteInstanceKnocked;
+ Logger.Debug ("Tasque remote control active.");
+ } else {
+ // If Tasque is already running, open the tasks window
+ // so the user gets some sort of feedback when they
+ // attempt to run Tasque again.
+ RemoteControl remote = null;
+ try {
+ remote = RemoteControl.GetInstance ();
+ remote.KnockKnock ();
+ } catch {}
+
+ Logger.Debug ("Tasque is already running. Exiting...");
+ return true;
+ }
+ } catch (Exception e) {
+ Logger.Debug ("Tasque remote control disabled (DBus exception): {0}", e.Message);
+ }
+ return false;
+#endif
+ }
+
+ protected override void ShowMainWindow ()
+ {
+ TaskWindow.ShowWindow ();
+ }
+
+ protected override event EventHandler RemoteInstanceKnocked;
+
+ void HandleRemoteInstanceKnocked ()
+ {
+ if (RemoteInstanceKnocked != null)
+ RemoteInstanceKnocked (this, EventArgs.Empty);
+ }
+
+ protected override void Dispose (bool disposing)
+ {
+ if (disposing)
+ remoteInstance.RemoteInstanceKnocked = null;
+ }
+
+ string confDir;
+#if LINUX
+ RemoteControl remoteInstance;
+#endif
}
}
diff --git a/src/Gtk.Tasque/RemoteControl.cs b/src/Gtk.Tasque/RemoteControl.cs
index ec74ce4..be8d7c5 100644
--- a/src/Gtk.Tasque/RemoteControl.cs
+++ b/src/Gtk.Tasque/RemoteControl.cs
@@ -21,15 +21,47 @@ namespace Tasque
[Interface ("org.gnome.Tasque.RemoteControl")]
public class RemoteControl : MarshalByRefObject
{
+ const string Namespace = "org.gnome.Tasque";
+ const string Path = "/org/gnome/Tasque/RemoteControl";
+
static Gdk.Pixbuf tasqueIcon;
static RemoteControl ()
{
tasqueIcon = Utilities.GetIcon ("tasque", 48);
}
- public RemoteControl()
+ public static RemoteControl GetInstance ()
{
+ BusG.Init ();
+
+ if (!Bus.Session.NameHasOwner (Namespace))
+ Bus.Session.StartServiceByName (Namespace);
+
+ return Bus.Session.GetObject<RemoteControl> (Namespace, new ObjectPath (Path));
}
+
+ public static RemoteControl Register ()
+ {
+ BusG.Init ();
+
+ var remoteControl = new RemoteControl ();
+ Bus.Session.Register (new ObjectPath (Path), remoteControl);
+
+ if (Bus.Session.RequestName (Namespace) != RequestNameReply.PrimaryOwner)
+ return null;
+
+ return remoteControl;
+ }
+
+ RemoteControl () {}
+
+ public void KnockKnock ()
+ {
+ if (RemoteInstanceKnocked != null)
+ RemoteInstanceKnocked ();
+ }
+
+ public Action RemoteInstanceKnocked { get; set; }
/// <summary>
/// Create a new task in Tasque using the given categoryName and name.
@@ -470,7 +502,6 @@ namespace Tasque
task.Delete ();
return true;
}
-
/// <summary>
/// Looks up a task by ID in the backend
diff --git a/src/libtasque/INativeApplication.cs b/src/libtasque/INativeApplication.cs
index 11a8f06..4ec1f1e 100644
--- a/src/libtasque/INativeApplication.cs
+++ b/src/libtasque/INativeApplication.cs
@@ -2,7 +2,7 @@ using System;
namespace Tasque
{
- public interface INativeApplication
+ public interface INativeApplication : IDisposable
{
string ConfDir { get; }
diff --git a/src/Gtk.Tasque/Logger.cs b/src/libtasque/Logger.cs
similarity index 100%
rename from src/Gtk.Tasque/Logger.cs
rename to src/libtasque/Logger.cs
diff --git a/src/libtasque/NativeApplication.cs b/src/libtasque/NativeApplication.cs
index 92565f2..ae28e34 100644
--- a/src/libtasque/NativeApplication.cs
+++ b/src/libtasque/NativeApplication.cs
@@ -43,7 +43,15 @@ namespace Tasque
Environment.Exit (exitcode);
}
- public abstract void Initialize (string[] args);
+ public virtual void Initialize (string[] args)
+ {
+ if (IsRemoteInstanceRunning ()) {
+ Logger.Info ("Another instance of Tasque is already running.");
+ Exit (0);
+ }
+
+ RemoteInstanceKnocked += delegate { ShowMainWindow (); };
+ }
public virtual void InitializeIdle () {}
@@ -59,6 +67,33 @@ namespace Tasque
public abstract void StartMainLoop ();
public event EventHandler Exiting;
+
+ /// <summary>
+ /// Determines whether this a remote instance is running.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if a remote instance is running; otherwise, <c>false</c>.
+ /// </returns>
+ protected abstract bool IsRemoteInstanceRunning ();
+
+ protected abstract void ShowMainWindow ();
+
+ protected abstract event EventHandler RemoteInstanceKnocked;
+
+ #region IDisposable implementation
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing) {}
+
+ ~NativeApplication ()
+ {
+ Dispose (false);
+ }
+ #endregion
}
}
diff --git a/src/libtasque/libtasque.csproj b/src/libtasque/libtasque.csproj
index f3503bf..8e078c7 100644
--- a/src/libtasque/libtasque.csproj
+++ b/src/libtasque/libtasque.csproj
@@ -72,6 +72,7 @@
</Compile>
<Compile Include="IBackendPreferences.cs" />
<Compile Include="NativeApplication.cs" />
+ <Compile Include="Logger.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="DateFormatters\" />
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]