[tasque/transition: 94/213] Outsource tray logic from Application.cs
- From: Antonius Riha <antoniusri src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tasque/transition: 94/213] Outsource tray logic from Application.cs
- Date: Wed, 29 Aug 2012 18:41:55 +0000 (UTC)
commit 65346c9dbc9445521547894cdd0dde9803c4ff8b
Author: Antonius Riha <antoniusriha gmail com>
Date: Mon Jul 30 16:15:10 2012 +0200
Outsource tray logic from Application.cs
* AppIndicatorTray.cs: Tray icon for Ubuntu's Unity desktop. This
should fix the bug, that the tray icon isn't displayed in Unity.
* StatusIconTray.cs: Fallback systray for non-Unity desktops
* GtkTray.cs: Common base class of the above two.
Note: AppIndicator tray and StatusIcon tray work a little different:
Toggling the main window in AppIndicator is done via a menu item
(due to a limitation of AppIndicator API),
whereas StatusIcon toggles via clicking the icon.
INSTALL | 13 ++
build/build.csproj | 3 +
src/Tasque.Gtk/AppIndicatorTray.cs | 51 +++++++
src/Tasque.Gtk/Application.cs | 287 ++++++------------------------------
src/Tasque.Gtk/GtkTray.cs | 225 ++++++++++++++++++++++++++++
src/Tasque.Gtk/StatusIconTray.cs | 51 +++++++
src/Tasque.Gtk/TaskWindow.cs | 1 +
src/Tasque.Gtk/Tasque.Gtk.csproj | 13 ++-
8 files changed, 404 insertions(+), 240 deletions(-)
---
diff --git a/INSTALL b/INSTALL
index 7d7c28d..6c0e146 100644
--- a/INSTALL
+++ b/INSTALL
@@ -15,6 +15,19 @@ opening the solution in Monodevelop. Otherwise Monodevelop will issue
warnings about some missing projects. Those projects are fetched during build.
+AppIndicator:
+For the systray icon to work on the Unity desktop appindicator-sharp is needed.
+By default appindicator support is enabled. It can be switched off by adding
+
+ /property:EnableAppIndicator=false
+
+to the command line, thus yielding
+
+ xbuild /property:Configuration=GtkLinuxDebug /property:EnableAppIndicator=false tasque.sln
+
+as the build command.
+
+
Instructions below are deprecated.
--------------------------------------------------------
diff --git a/build/build.csproj b/build/build.csproj
index 544dac4..27e83ef 100644
--- a/build/build.csproj
+++ b/build/build.csproj
@@ -137,6 +137,9 @@
<None Include="..\src\tasque\tasque.csproj">
<Link>tasque.csproj</Link>
</None>
+ <None Include="..\INSTALL">
+ <Link>INSTALL</Link>
+ </None>
</ItemGroup>
<ItemGroup>
<Compile Include="SetDataAtBuildTime.cs" />
diff --git a/src/Tasque.Gtk/AppIndicatorTray.cs b/src/Tasque.Gtk/AppIndicatorTray.cs
new file mode 100644
index 0000000..0be991f
--- /dev/null
+++ b/src/Tasque.Gtk/AppIndicatorTray.cs
@@ -0,0 +1,51 @@
+//
+// AppIndicatorTray.cs
+//
+// Author:
+// Antonius Riha <antoniusriha gmail com>
+//
+// Copyright (c) 2012 Antonius Riha
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using Gtk;
+using AppIndicator;
+
+namespace Tasque
+{
+ public class AppIndicatorTray : GtkTray
+ {
+ public AppIndicatorTray ()
+ {
+ appIndicator = new ApplicationIndicator ("TasqueTray", IconName,
+ AppIndicator.Category.ApplicationStatus);
+ appIndicator.Status = Status.Active;
+
+ var menu = Menu;
+ var toggleTaskWindowMenuItem = new MenuItem ();
+ ToggleTaskWindowAction.ConnectProxy (toggleTaskWindowMenuItem);
+ menu.Insert (toggleTaskWindowMenuItem, 0);
+ menu.Insert (new SeparatorMenuItem (), 1);
+ menu.ShowAll ();
+
+ appIndicator.Menu = menu;
+ }
+
+ ApplicationIndicator appIndicator;
+ }
+}
diff --git a/src/Tasque.Gtk/Application.cs b/src/Tasque.Gtk/Application.cs
index d7d3789..4894fc3 100644
--- a/src/Tasque.Gtk/Application.cs
+++ b/src/Tasque.Gtk/Application.cs
@@ -40,7 +40,6 @@ using Gtk;
using Gdk;
using Mono.Unix;
using Mono.Unix.Native;
-using Tasque.UIModel.Legacy;
using System.Diagnostics;
@@ -56,10 +55,9 @@ namespace Tasque
private static System.Object locker = new System.Object();
private NativeApplication nativeApp;
- private Gtk.StatusIcon trayIcon;
+ private GtkTray trayIcon;
private Preferences preferences;
private Backend backend;
- private TaskGroupModel overdue_tasks, today_tasks, tomorrow_tasks;
private PreferencesDialog preferencesDialog;
private bool quietStart = false;
@@ -73,22 +71,6 @@ namespace Tasque
private Backend customBackend;
- private UIManager uiManager;
- private const string menuXml = @"
-<ui>
- <popup name=""TrayIconMenu"">
- <menuitem action=""NewTaskAction""/>
- <separator/>
- <menuitem action=""PreferencesAction""/>
- <menuitem action=""AboutAction""/>
- <separator/>
- <menuitem action=""RefreshAction""/>
- <separator/>
- <menuitem action=""QuitAction""/>
- </popup>
-</ui>
-";
-
public static Backend Backend
{
get { return Application.Instance.backend; }
@@ -125,16 +107,20 @@ namespace Tasque
}
}
- public UIManager UIManager
- {
- get { return uiManager; }
- }
+ public event EventHandler BackendChanged;
- public StatusIcon Tray
+ void OnBackendChanged ()
{
- get { return trayIcon; }
+ if (BackendChanged != null)
+ BackendChanged (this, EventArgs.Empty);
}
-
+
+ public TaskGroupModel OverdueTasks { get; private set; }
+
+ public TaskGroupModel TodayTasks { get; private set; }
+
+ public TaskGroupModel TomorrowTasks { get; private set; }
+
public static Preferences Preferences
{
get { return Application.Instance.preferences; }
@@ -155,13 +141,9 @@ namespace Tasque
nativeApp = new GnomeApplication ();
#endif
nativeApp.Initialize (args);
-
- RegisterUIManager ();
preferences = new Preferences (nativeApp.ConfDir);
-
-
string potentialBackendClassName = null;
for (int i = 0; i < args.Length; i++) {
@@ -320,9 +302,11 @@ namespace Tasque
}
// Initialize the new backend
+ var oldBackend = backend;
this.backend = value;
if (this.backend == null) {
- RefreshTrayIconTooltip ();
+ if (trayIcon != null)
+ trayIcon.RefreshTrayIconTooltip ();
return;
}
@@ -338,10 +322,14 @@ namespace Tasque
}
RebuildTooltipTaskGroupModels ();
- RefreshTrayIconTooltip ();
+ if (trayIcon != null)
+ trayIcon.RefreshTrayIconTooltip ();
Debug.WriteLine("Configuration status: {0}",
this.backend.Configured.ToString());
+
+ if (backend != oldBackend)
+ OnBackendChanged ();
}
private bool InitializeIdle()
@@ -360,7 +348,7 @@ namespace Tasque
}
}
- SetupTrayIcon ();
+ trayIcon = GtkTray.CreateTray ();
if (backend == null) {
// Pop open the preferences dialog so the user can choose a
@@ -404,30 +392,16 @@ namespace Tasque
UnhookFromTooltipTaskGroupModels ();
RebuildTooltipTaskGroupModels ();
- RefreshTrayIconTooltip ();
+ if (trayIcon != null)
+ trayIcon.RefreshTrayIconTooltip ();
}
return true;
}
- private void SetupTrayIcon ()
- {
- trayIcon = new Gtk.StatusIcon();
- trayIcon.Pixbuf = Utilities.GetIcon ("tasque-24", 24);
-
- // hooking event
- trayIcon.Activate += OnTrayIconClick;
- trayIcon.PopupMenu += OnTrayIconPopupMenu;
-
- // showing the trayicon
- trayIcon.Visible = true;
-
- RefreshTrayIconTooltip ();
- }
-
void UnhookFromTooltipTaskGroupModels ()
{
- foreach (TaskGroupModel model in new TaskGroupModel[] { overdue_tasks, today_tasks, tomorrow_tasks })
+ foreach (TaskGroupModel model in new TaskGroupModel[] { OverdueTasks, TodayTasks, TomorrowTasks })
{
if (model == null)
continue;
@@ -438,24 +412,25 @@ namespace Tasque
void OnTooltipModelChanged (object sender, EventArgs args)
{
- RefreshTrayIconTooltip ();
+ if (trayIcon != null)
+ trayIcon.RefreshTrayIconTooltip ();
}
void RebuildTooltipTaskGroupModels ()
{
if (backend == null || backend.Tasks2 == null) {
- overdue_tasks = null;
- today_tasks = null;
- tomorrow_tasks = null;
+ OverdueTasks = null;
+ TodayTasks = null;
+ TomorrowTasks = null;
return;
}
- overdue_tasks = TaskGroupModelFactory.CreateOverdueModel (backend.Tasks);
- today_tasks = TaskGroupModelFactory.CreateTodayModel (backend.Tasks);
- tomorrow_tasks = TaskGroupModelFactory.CreateTomorrowModel (backend.Tasks);
+ OverdueTasks = TaskGroupModelFactory.CreateOverdueModel (backend.Tasks);
+ TodayTasks = TaskGroupModelFactory.CreateTodayModel (backend.Tasks);
+ TomorrowTasks = TaskGroupModelFactory.CreateTomorrowModel (backend.Tasks);
- foreach (TaskGroupModel model in new TaskGroupModel[] { overdue_tasks, today_tasks, tomorrow_tasks })
+ foreach (TaskGroupModel model in new TaskGroupModel[] { OverdueTasks, TodayTasks, TomorrowTasks })
{
if (model == null)
continue;
@@ -463,154 +438,24 @@ namespace Tasque
model.CollectionChanged += OnTooltipModelChanged;
}
}
-
- private void RefreshTrayIconTooltip ()
- {
- if (trayIcon == null) {
- return;
- }
-
- StringBuilder sb = new StringBuilder ();
- if (overdue_tasks != null) {
- int count = overdue_tasks.Count;
-
- if (count > 0) {
- sb.Append (String.Format (Catalog.GetPluralString ("{0} task is Overdue\n", "{0} tasks are Overdue\n", count), count));
- }
- }
-
- if (today_tasks != null) {
- int count = today_tasks.Count;
-
- if (count > 0) {
- sb.Append (String.Format (Catalog.GetPluralString ("{0} task for Today\n", "{0} tasks for Today\n", count), count));
- }
- }
-
- if (tomorrow_tasks != null) {
- int count = tomorrow_tasks.Count;
-
- if (count > 0) {
- sb.Append (String.Format (Catalog.GetPluralString ("{0} task for Tomorrow\n", "{0} tasks for Tomorrow\n", count), count));
- }
- }
-
- if (sb.Length == 0) {
- // Translators: This is the status icon's tooltip. When no tasks are overdue, due today, or due tomorrow, it displays this fun message
- trayIcon.Tooltip = Catalog.GetString ("Tasque Rocks");
- return;
- }
-
- trayIcon.Tooltip = sb.ToString ().TrimEnd ('\n');
- }
-
- private void OnPreferences (object sender, EventArgs args)
- {
- Trace.TraceInformation ("OnPreferences called");
- if (preferencesDialog == null) {
- preferencesDialog = new PreferencesDialog ();
- preferencesDialog.Hidden += OnPreferencesDialogHidden;
- }
-
- preferencesDialog.Present ();
- }
-
private void OnPreferencesDialogHidden (object sender, EventArgs args)
{
preferencesDialog.Destroy ();
preferencesDialog = null;
}
- public static void ShowPreferences()
+ public static void ShowPreferences ()
{
- application.OnPreferences(null, EventArgs.Empty);
- }
-
- private void OnAbout (object sender, EventArgs args)
- {
- string [] authors = new string [] {
- "Boyd Timothy <btimothy gmail com>",
- "Calvin Gaisford <calvinrg gmail com>",
- "Sandy Armstrong <sanfordarmstrong gmail com>",
- "Brian G. Merrell <bgmerrell novell com>"
- };
-
- /* string [] documenters = new string [] {
- "Calvin Gaisford <calvinrg gmail com>"
- };
- */
-
- string translators = Catalog.GetString ("translator-credits");
- if (translators == "translator-credits")
- translators = null;
-
- Gtk.AboutDialog about = new Gtk.AboutDialog ();
- about.ProgramName = "Tasque";
- about.Version = GlobalDefines.Version;
- about.Logo = Utilities.GetIcon("tasque-48", 48);
- about.Copyright =
- Catalog.GetString ("Copyright \xa9 2008 Novell, Inc.");
- about.Comments = Catalog.GetString ("A Useful Task List");
- about.Website = "http://live.gnome.org/Tasque";
- about.WebsiteLabel = Catalog.GetString("Tasque Project Homepage");
- about.Authors = authors;
- //about.Documenters = documenters;
- about.TranslatorCredits = translators;
- about.IconName = "tasque";
- about.SetSizeRequest(300, 300);
- about.Run ();
- about.Destroy ();
-
- }
-
-
- private void OnShowTaskWindow (object sender, EventArgs args)
- {
- TaskWindow.ShowWindow();
- }
-
- private void OnNewTask (object sender, EventArgs args)
- {
- // Show the TaskWindow and then cause a new task to be created
- TaskWindow.ShowWindow ();
- TaskWindow.GrabNewTaskEntryFocus ();
- }
-
- private void OnQuit (object sender, EventArgs args)
- {
- Trace.TraceInformation ("OnQuit called - terminating application");
- if (backend != null) {
- UnhookFromTooltipTaskGroupModels ();
- backend.Cleanup();
+ var app = application;
+ Trace.TraceInformation ("OnPreferences called");
+ if (app.preferencesDialog == null) {
+ app.preferencesDialog = new PreferencesDialog ();
+ app.preferencesDialog.Hidden += OnPreferencesDialogHidden;
}
- TaskWindow.SavePosition();
-
- nativeApp.QuitMainLoop ();
- }
-
- private void OnRefreshAction (object sender, EventArgs args)
- {
- Application.Backend.Refresh();
- }
-
- private void OnTrayIconClick (object sender, EventArgs args) // handler for mouse click
- {
- TaskWindow.ToggleWindowVisible ();
- }
-
- private void OnTrayIconPopupMenu (object sender, EventArgs args)
- {
- Menu popupMenu = (Menu) uiManager.GetWidget ("/TrayIconMenu");
-
- bool backendItemsSensitive = (backend != null && backend.Initialized);
- uiManager.GetAction ("/TrayIconMenu/NewTaskAction").Sensitive = backendItemsSensitive;
- uiManager.GetAction ("/TrayIconMenu/RefreshAction").Sensitive = backendItemsSensitive;
-
- popupMenu.ShowAll(); // shows everything
- popupMenu.Popup();
- }
+ app.preferencesDialog.Present ();
+ }
public static void Main(string[] args)
{
@@ -658,50 +503,14 @@ namespace Tasque
public void Quit ()
{
- OnQuit (null, null);
- }
+ Trace.TraceInformation ("OnQuit called - terminating application");
+ if (backend != null) {
+ UnhookFromTooltipTaskGroupModels ();
+ backend.Cleanup ();
+ }
+ TaskWindow.SavePosition ();
- private void RegisterUIManager ()
- {
- ActionGroup trayActionGroup = new ActionGroup ("Tray");
- trayActionGroup.Add (new ActionEntry [] {
- new ActionEntry ("NewTaskAction",
- Stock.New,
- Catalog.GetString ("New Task ..."),
- null,
- null,
- OnNewTask),
-
- new ActionEntry ("ShowTasksAction",
- null,
- Catalog.GetString ("Show Tasks ..."),
- null,
- null,
- OnShowTaskWindow),
-
- new ActionEntry ("AboutAction",
- Stock.About,
- OnAbout),
-
- new ActionEntry ("PreferencesAction",
- Stock.Preferences,
- OnPreferences),
-
- new ActionEntry ("RefreshAction",
- Stock.Execute,
- Catalog.GetString ("Refresh Tasks ..."),
- null,
- null,
- OnRefreshAction),
-
- new ActionEntry ("QuitAction",
- Stock.Quit,
- OnQuit)
- });
-
- uiManager = new UIManager ();
- uiManager.AddUiFromString (menuXml);
- uiManager.InsertActionGroup (trayActionGroup, 0);
+ nativeApp.QuitMainLoop ();
}
}
}
diff --git a/src/Tasque.Gtk/GtkTray.cs b/src/Tasque.Gtk/GtkTray.cs
new file mode 100644
index 0000000..a3f8d17
--- /dev/null
+++ b/src/Tasque.Gtk/GtkTray.cs
@@ -0,0 +1,225 @@
+//
+// GtkTray.cs
+//
+// Author:
+// Antonius Riha <antoniusriha gmail com>
+//
+// Copyright (c) 2012 Antonius Riha
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Text;
+using Mono.Unix;
+using Gtk;
+
+namespace Tasque
+{
+ public class GtkTray : IDisposable
+ {
+ public static GtkTray CreateTray ()
+ {
+#if APPINDICATOR
+ return new AppIndicatorTray ();
+#else
+ return new StatusIconTray ();
+#endif
+ }
+
+ protected GtkTray ()
+ {
+ UpdateBackend ();
+ Application.Instance.BackendChanged += HandleBackendChanged;
+ RefreshTrayIconTooltip ();
+ }
+
+ #region IDisposable implementation
+ public void Dispose ()
+ {
+ var app = Application.Instance;
+ if (app != null)
+ app.BackendChanged -= HandleBackendChanged;
+ }
+ #endregion
+
+ public void RefreshTrayIconTooltip ()
+ {
+ var oldTooltip = Tooltip;
+
+ var overdueTasks = Application.Instance.OverdueTasks;
+ var todayTasks = Application.Instance.TodayTasks;
+ var tomorrowTasks = Application.Instance.TomorrowTasks;
+
+ var sb = new StringBuilder ();
+ if (overdueTasks != null) {
+ int count = overdueTasks.Count;
+
+ if (count > 0)
+ sb.Append (String.Format (Catalog.GetPluralString ("{0} task is Overdue\n",
+ "{0} tasks are Overdue\n", count), count));
+ }
+
+ if (todayTasks != null) {
+ int count = todayTasks.Count;
+
+ if (count > 0)
+ sb.Append (String.Format (Catalog.GetPluralString ("{0} task for Today\n",
+ "{0} tasks for Today\n", count), count));
+ }
+
+ if (tomorrowTasks != null) {
+ int count = tomorrowTasks.Count;
+
+ if (count > 0)
+ sb.Append (String.Format (Catalog.GetPluralString ("{0} task for Tomorrow\n",
+ "{0} tasks for Tomorrow\n", count), count));
+ }
+
+ if (sb.Length == 0) {
+ // Translators: This is the status icon's tooltip. When no tasks are overdue, due
+ // today, or due tomorrow, it displays this fun message
+ Tooltip = Catalog.GetString ("Tasque Rocks");
+ return;
+ }
+
+ Tooltip = sb.ToString ().TrimEnd ('\n');
+
+ if (Tooltip != oldTooltip)
+ OnTooltipChanged ();
+ }
+
+ protected string IconName { get { return "tasque-24"; } }
+
+ protected Menu Menu {
+ get {
+ if (uiManager == null)
+ RegisterUIManager ();
+ return (Menu)uiManager.GetWidget ("/TrayIconMenu");
+ }
+ }
+
+ protected Gtk.Action ToggleTaskWindowAction { get; private set; }
+
+ protected string Tooltip { get; private set; }
+
+ protected virtual void OnTooltipChanged () {}
+
+ void HandleBackendChanged (object sender, EventArgs e)
+ {
+ UpdateBackend ();
+ }
+
+ void HandleBackendInitialized (object sender, EventArgs e)
+ {
+ UpdateActionSensitivity ();
+ }
+
+ void OnAbout (object sender, EventArgs args)
+ {
+ var authorsList = GlobalDefines.Authors;
+ var authors = new string [authorsList.Count];
+ authorsList.CopyTo (authors, 0);
+
+ string translators = Catalog.GetString ("translator-credits");
+ if (translators == "translator-credits")
+ translators = null;
+
+ var about = new AboutDialog ();
+ about.ProgramName = "Tasque";
+ about.Version = GlobalDefines.Version;
+ about.Logo = Utilities.GetIcon ("tasque-48", 48);
+ about.Copyright = Catalog.GetString ("Copyright \xa9 2008 Novell, Inc.");
+ about.License = GlobalDefines.License;
+ about.Comments = Catalog.GetString ("A Useful Task List");
+ about.Website = GlobalDefines.Website;
+ about.WebsiteLabel = Catalog.GetString("Tasque Project Homepage");
+ about.Authors = authors;
+ about.TranslatorCredits = translators;
+ about.IconName = "tasque";
+ about.SetSizeRequest(300, 300);
+ about.Run ();
+ about.Destroy ();
+ }
+
+ void RegisterUIManager ()
+ {
+ var trayActionGroup = new ActionGroup ("Tray");
+ trayActionGroup.Add (new ActionEntry [] {
+ new ActionEntry ("NewTaskAction", Stock.New, Catalog.GetString ("New Task ..."), null, null, delegate {
+ // Show the TaskWindow and then cause a new task to be created
+ TaskWindow.ShowWindow ();
+ TaskWindow.GrabNewTaskEntryFocus ();
+ }),
+
+ new ActionEntry ("AboutAction", Stock.About, OnAbout),
+
+ new ActionEntry ("PreferencesAction", Stock.Preferences, delegate { Application.ShowPreferences (); }),
+
+ new ActionEntry ("RefreshAction", Stock.Execute, Catalog.GetString ("Refresh Tasks ..."),
+ null, null, delegate { Application.Backend.Refresh(); }),
+
+ new ActionEntry ("QuitAction", Stock.Quit, delegate { Application.Instance.Quit (); })
+ });
+
+ ToggleTaskWindowAction = new Gtk.Action ("ToggleTaskWindowAction", "Toggle Task Window");
+ ToggleTaskWindowAction.ActionGroup = trayActionGroup;
+ ToggleTaskWindowAction.Activated += delegate { TaskWindow.ToggleWindowVisible (); };
+
+ uiManager = new UIManager ();
+ uiManager.AddUiFromString (MenuXml);
+ uiManager.InsertActionGroup (trayActionGroup, 0);
+ }
+
+ void UpdateActionSensitivity ()
+ {
+ var backend = Application.Backend;
+ bool backendItemsSensitive = (backend != null && backend.Initialized);
+ uiManager.GetAction ("/TrayIconMenu/NewTaskAction").Sensitive = backendItemsSensitive;
+ uiManager.GetAction ("/TrayIconMenu/RefreshAction").Sensitive = backendItemsSensitive;
+ }
+
+ void UpdateBackend ()
+ {
+ if (backend != null)
+ backend.BackendInitialized -= HandleBackendInitialized;
+ backend = Application.Backend;
+
+ if (backend != null)
+ backend.BackendInitialized += HandleBackendInitialized;
+
+ UpdateActionSensitivity ();
+ }
+
+ Backend backend;
+ UIManager uiManager;
+ const string MenuXml = @"
+<ui>
+ <popup name=""TrayIconMenu"">
+ <menuitem action=""NewTaskAction""/>
+ <separator/>
+ <menuitem action=""PreferencesAction""/>
+ <menuitem action=""AboutAction""/>
+ <separator/>
+ <menuitem action=""RefreshAction""/>
+ <separator/>
+ <menuitem action=""QuitAction""/>
+ </popup>
+</ui>
+";
+ }
+}
diff --git a/src/Tasque.Gtk/StatusIconTray.cs b/src/Tasque.Gtk/StatusIconTray.cs
new file mode 100644
index 0000000..b056b17
--- /dev/null
+++ b/src/Tasque.Gtk/StatusIconTray.cs
@@ -0,0 +1,51 @@
+//
+// StatusIconTray.cs
+//
+// Author:
+// Antonius Riha <antoniusriha gmail com>
+//
+// Copyright (c) 2012 Antonius Riha
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using Gtk;
+
+namespace Tasque
+{
+ public class StatusIconTray : GtkTray
+ {
+ public StatusIconTray ()
+ {
+ tray = new StatusIcon (Utilities.GetIcon (IconName, 24));
+ tray.Visible = true;
+ tray.Activate += delegate { ToggleTaskWindowAction.Activate (); };
+ tray.PopupMenu += (sender, e) => {
+ var popupMenu = Menu;
+ popupMenu.ShowAll (); // shows everything
+ tray.PresentMenu (popupMenu, (uint)e.Args [0], (uint)e.Args [1]);
+ };
+ }
+
+ protected override void OnTooltipChanged ()
+ {
+ tray.Tooltip = Tooltip;
+ }
+
+ StatusIcon tray;
+ }
+}
diff --git a/src/Tasque.Gtk/TaskWindow.cs b/src/Tasque.Gtk/TaskWindow.cs
index 80a2484..1938d3e 100644
--- a/src/Tasque.Gtk/TaskWindow.cs
+++ b/src/Tasque.Gtk/TaskWindow.cs
@@ -37,6 +37,7 @@ using Mono.Unix;
using Tasque;
using CollectionTransforms;
using System.Collections;
+using System.Diagnostics;
namespace Tasque
{
diff --git a/src/Tasque.Gtk/Tasque.Gtk.csproj b/src/Tasque.Gtk/Tasque.Gtk.csproj
index 39ed83a..d5859aa 100644
--- a/src/Tasque.Gtk/Tasque.Gtk.csproj
+++ b/src/Tasque.Gtk/Tasque.Gtk.csproj
@@ -10,6 +10,7 @@
<AssemblyName>Tasque.Gtk</AssemblyName>
<RootNamespace>Tasque</RootNamespace>
<ReleaseVersion>0.1.10</ReleaseVersion>
+ <EnableAppIndicator Condition=" '$(EnableAppIndicator)' == '' ">true</EnableAppIndicator>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'GtkLinuxDebug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -17,6 +18,7 @@
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE;GTKLINUX</DefineConstants>
+ <DefineConstants Condition=" '$(EnableAppIndicator)' ">$(DefineConstants);APPINDICATOR</DefineConstants>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'GtkLinuxRelease|AnyCPU' ">
@@ -24,6 +26,7 @@
<Optimize>true</Optimize>
<OutputPath>bin\LinuxRelease</OutputPath>
<DefineConstants>TRACE;GTKLINUX</DefineConstants>
+ <DefineConstants Condition=" '$(EnableAppIndicator)' ">$(DefineConstants);APPINDICATOR</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CustomCommands>
@@ -87,13 +90,16 @@
</Reference>
<Reference Include="notify-sharp, Version=0.4.0.0, Culture=neutral, PublicKeyToken=2df29c54e245917a">
<Private>False</Private>
- <Package>notify-sharp</Package>
</Reference>
<Reference Include="NDesk.DBus.GLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f6716e4f9b2ed099">
<Private>False</Private>
<Package>ndesk-dbus-glib-1.0</Package>
</Reference>
<Reference Include="WindowsBase" />
+ <Reference Include="appindicator-sharp, Version=0.2.0.0, Culture=neutral, PublicKeyToken=bcae265d1c7ab4c2">
+ <Private>False</Private>
+ <Package>appindicator-sharp-0.1</Package>
+ </Reference>
</ItemGroup>
<ItemGroup>
<None Include="..\..\data\sounds\notify.wav">
@@ -126,6 +132,8 @@
<Compile Include="TaskWindow.cs" />
<Compile Include="Utilities.cs" />
<Compile Include="GtkApplicationBase.cs" />
+ <Compile Include="StatusIconTray.cs" />
+ <Compile Include="GtkTray.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'GtkWinDebug' or '$(Configuration)' == 'GtkWinRelease' ">
<Compile Include="GtkWinApplication.cs" />
@@ -134,6 +142,9 @@
<Compile Include="GtkLinuxApplication.cs" />
<Compile Include="RemoteControl.cs" />
</ItemGroup>
+ <ItemGroup Condition=" '$(EnableAppIndicator)' ">
+ <Compile Include="AppIndicatorTray.cs" />
+ </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
<Folder Include="data\" />
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]