diff -Nru docky-2.0.2/AUTHORS docky-2.0.4/AUTHORS --- docky-2.0.2/AUTHORS 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/AUTHORS 2010-05-25 14:22:51.826113858 +0200 @@ -13,6 +13,6 @@ Robert Dyer Chris Szikszoy Rico Tzschichholz -Seif Lofty +Seif Lotfy Chris Halse Rogers Alex Launi diff -Nru docky-2.0.2/configure docky-2.0.4/configure --- docky-2.0.2/configure 2010-04-12 15:07:30.723611439 +0200 +++ docky-2.0.4/configure 2010-05-31 08:00:13.405621764 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for docky 2.0.2. +# Generated by GNU Autoconf 2.65 for docky 2.0.4. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -609,8 +609,8 @@ # Identity of this package. PACKAGE_NAME='docky' PACKAGE_TARNAME='docky' -PACKAGE_VERSION='2.0.2' -PACKAGE_STRING='docky 2.0.2' +PACKAGE_VERSION='2.0.4' +PACKAGE_STRING='docky 2.0.4' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1465,7 +1465,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures docky 2.0.2 to adapt to many kinds of systems. +\`configure' configures docky 2.0.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1531,7 +1531,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of docky 2.0.2:";; + short | recursive ) echo "Configuration of docky 2.0.4:";; esac cat <<\_ACEOF @@ -1714,7 +1714,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -docky configure 2.0.2 +docky configure 2.0.4 generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. @@ -2079,7 +2079,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by docky $as_me 2.0.2, which was +It was created by docky $as_me 2.0.4, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -2887,7 +2887,7 @@ # Define the identity of the package. PACKAGE='docky' - VERSION='2.0.2' + VERSION='2.0.4' cat >>confdefs.h <<_ACEOF @@ -9856,7 +9856,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by docky $as_me 2.0.2, which was +This file was extended by docky $as_me 2.0.4, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -9913,7 +9913,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -docky config.status 2.0.2 +docky config.status 2.0.4 configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" diff -Nru docky-2.0.2/configure.ac docky-2.0.4/configure.ac --- docky-2.0.2/configure.ac 2010-04-12 15:05:39.494862715 +0200 +++ docky-2.0.4/configure.ac 2010-05-31 07:57:05.815621942 +0200 @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.54]) -AC_INIT([docky], [2.0.2]) +AC_INIT([docky], [2.0.4]) AM_INIT_AUTOMAKE([foreign tar-pax]) AC_CONFIG_MACRO_DIR([m4]) diff -Nru docky-2.0.2/debian/changelog docky-2.0.4/debian/changelog --- docky-2.0.2/debian/changelog 2010-05-31 10:37:44.000000000 +0200 +++ docky-2.0.4/debian/changelog 2010-05-31 10:37:44.000000000 +0200 @@ -1,3 +1,91 @@ +docky (2.0.4-0ubuntu1) lucid; urgency=low + + [ Iain Lane ] + * debian/control: Specify that only python version >= 2.5 are supported, + thanks to Stefano Rivera for the report (Closes: #582046) + + [ Rico Tzschichholz ] + * New upstream release 2.0.4 "Do you think you're better off alone?", + changes include: + + fix positioning of menus/hovers on multimon setups (LP: #544047) + + make settings dialog smaller so it fits on netbook screens (LP: #581458) + + FileApplicationProvider.PinToDock misses a handle-removal + This caused a duplicated item when restarting a just pinned application and + leads to a crash when trying to pin the new item (LP: #585136) + + update transient items when moving the active window (LP: #581077) + + fix crash when a file is on the dock where this file no longer exists + (LP: #581074) + + fix drag'n'drop-hover-strings (LP: #556041) + + add call to GLib.Thread.Init (LP: #586969) + + Window-Matching + - better OpenOffice handling (LP: #486887) (LP: #580275) + (LP: #504486) (LP: #580275) + + Helper + - fix a crash regarding helpers terminating + - fix killing helpers from prefs menu + - fix potential crash when disabling helpers + - cleanup the helpers, fix a few possible leaks in them + + Clock: fix problems with the small clock rendering + + GMail: + - fix compose mail url in GMail docklet for Google app domains (LP: #582212) + - fix crash when removing a gmail label (LP: #576596) + - refresh be set up to 1 day (1440 mins) long (LP: #580441) + - missing string internationalization in GMail + + RecentDocuments: better locking to avoid crashes when clearing + recent documents (LP: #580723) + + Weather: make sure weather doesn't reload when prefs open (LP: #580314) + + Bookmarks: stop spurious errors when dragging files over + unmounted bookmarks (LP: #580361) + + NPR: fix failing to load after network comes back up (LP: #523155) + + make banshee and rhythmbox helper a bit smarter looking + for art-cover-files (LP: #578254) + + fix class-names in the deluge helper + + change open terminal here helper to use the gnome default terminal, + with a fallback to gnome-terminal if the default is not set + + fix issues with newer zeitgeist version (LP: #570286) + * remove quilt patchsys and obsolete patches + + -- Rico Tzschichholz Mon, 31 May 2010 10:25:54 +0200 + +docky (2.0.3.1-2) unstable; urgency=low + + * debian/patches/mail_label_crash: Add patch cherrypicked from upstream to + fix a crash bug when deleting mail labels. + * debian/patches/window_grouping_reliability: Add patch cherrypicked from + upstream to improve the window grouping reliability. Previously some + applications, particularly OOo, would show two icons when the windows + should have been grouped into one. + * debian/control: Add python dep to docky manually. When we stopped byte + compiling the helpers, this dependency wasn't removed, but we do still + need to have a python interpreter around to use them. + + -- Iain Lane Fri, 14 May 2010 09:32:56 +0100 + +docky (2.0.3.1-1) unstable; urgency=low + + * New upstream release 2.0.3.1 "You should have heard from us by now", + changes include: + + fix gnome-keyring related crash in Lucid caused by GMail docklet + (LP: #555562) + + catch exception for read-failure of cxoffice launcher (LP: #573294) + + check if authentication is used before using network proxy + + make sure to update screen regions when showing menus + + make transparent themed docks still glow in configuration mode + (LP: #572416) + + Memory Leaks + - some unlinked handlers and pixbufs (DockItemMenu, WindowDockItem, ...) + - proper disposal of tile-widgets in preferences dialog + - properly using DesktopAppInfo for launching application + + GMail: fix exception when reloading (LP: #573991) + + CLOCK: popup menu must always show icons (LP: #574003) + + helpers crash when dbus isn't available (LP: #540688) + * debian/rules: Don't byte compile python helpers as this causes them to + appear in the prefs window twice (and the compiled ones don't work) + * debian/control: Add dep on librsvg2-common to fix installability when this + isn't otherwise available. + + -- Iain Lane Tue, 04 May 2010 16:15:39 +0100 + docky (2.0.2-1) unstable; urgency=low [ Stefan Ebner ] diff -Nru docky-2.0.2/debian/control docky-2.0.4/debian/control --- docky-2.0.2/debian/control 2010-05-31 10:37:44.000000000 +0200 +++ docky-2.0.4/debian/control 2010-05-31 10:37:44.000000000 +0200 @@ -27,6 +27,7 @@ libgtk2.0-dev, libglib2.0-dev Standards-Version: 3.8.4 +XS-Python-Version: >= 2.5 Vcs-Git: git://git.debian.org/git/pkg-cli-apps/packages/docky.git Vcs-Browser: http://git.debian.org/?p=pkg-cli-apps/packages/docky.git Homepage: https://launchpad.net/docky @@ -36,7 +37,8 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${cli:Depends}, - ${python:Depends}, + python, + librsvg2-common, python-docky Description: Elegant, powerful, clean dock A full fledged dock application that makes opening common applications and @@ -62,6 +64,7 @@ ${misc:Depends}, python-gobject, python-dbus +XB-Python-Version: ${python:Versions} Description: Elegant, powerful, clean dock - Python support library A full fledged dock application that makes opening common applications and managing windows easier and quicker. Docky is fully integrated into the GNOME diff -Nru docky-2.0.2/debian/README.source docky-2.0.4/debian/README.source --- docky-2.0.2/debian/README.source 1970-01-01 01:00:00.000000000 +0100 +++ docky-2.0.4/debian/README.source 2010-05-31 10:37:44.000000000 +0200 @@ -0,0 +1,58 @@ +This package uses quilt to manage all modifications to the upstream +source. Changes are stored in the source package as diffs in +debian/patches and applied during the build. + +To configure quilt to use debian/patches instead of patches, you want +either to export QUILT_PATCHES=debian/patches in your environment +or use this snippet in your ~/.quiltrc: + + for where in ./ ../ ../../ ../../../ ../../../../ ../../../../../; do + if [ -e ${where}debian/rules -a -d ${where}debian/patches ]; then + export QUILT_PATCHES=debian/patches + break + fi + done + +To get the fully patched source after unpacking the source package, cd to +the root level of the source package and run: + + quilt push -a + +The last patch listed in debian/patches/series will become the current +patch. + +To add a new set of changes, first run quilt push -a, and then run: + + quilt new + +where is a descriptive name for the patch, used as the filename in +debian/patches. Then, for every file that will be modified by this patch, +run: + + quilt add + +before editing those files. You must tell quilt with quilt add what files +will be part of the patch before making changes or quilt will not work +properly. After editing the files, run: + + quilt refresh + +to save the results as a patch. + +Alternately, if you already have an external patch and you just want to +add it to the build system, run quilt push -a and then: + + quilt import -P /path/to/patch + quilt push -a + +(add -p 0 to quilt import if needed). as above is the filename to +use in debian/patches. The last quilt push -a will apply the patch to +make sure it works properly. + +To remove an existing patch from the list of patches that will be applied, +run: + + quilt delete + +You may need to run quilt pop -a to unapply patches first before running +this command. diff -Nru docky-2.0.2/debian/rules docky-2.0.4/debian/rules --- docky-2.0.2/debian/rules 2010-05-31 10:37:44.000000000 +0200 +++ docky-2.0.4/debian/rules 2010-05-31 10:37:44.000000000 +0200 @@ -6,7 +6,8 @@ include /usr/share/cli-common/cli.make override_dh_pysupport: - dh_pysupport usr/share/docky/helpers +# Don't byte compile helpers — causes broken ones to also show up in prefs + dh_pysupport -X /usr/share/docky/helpers/ override_dh_auto_configure: dh_auto_configure -- MCS=/usr/bin/mono-csc diff -Nru docky-2.0.2/Docky/AssemblyInfo.cs docky-2.0.4/Docky/AssemblyInfo.cs --- docky-2.0.2/Docky/AssemblyInfo.cs 2010-04-12 15:07:34.337361264 +0200 +++ docky-2.0.4/Docky/AssemblyInfo.cs 2010-05-31 08:00:18.424372989 +0200 @@ -46,7 +46,7 @@ // // You can specify all values by your own or you can build default build and revision // numbers with the '*' character (the default): -[assembly: AssemblyVersion("1210")] +[assembly: AssemblyVersion("1266")] // The following attributes specify the key for the sign of your assembly. See the // .NET Framework documentation for more information about signing. @@ -58,8 +58,8 @@ { internal static class AssemblyInfo { - public const string DisplayVersion = "2.0.2"; - public const string VersionDetails = "bzr docky-2.0 r1210"; + public const string DisplayVersion = "2.0.4"; + public const string VersionDetails = "bzr docky-2.0 r1266"; public const string LocaleDirectory = "/usr/share/locale"; public const string InstallData = "/usr/share"; } diff -Nru docky-2.0.2/Docky/Docky/ConfigurationWindow.cs docky-2.0.4/Docky/Docky/ConfigurationWindow.cs --- docky-2.0.2/Docky/Docky/ConfigurationWindow.cs 2010-04-12 13:46:41.763611427 +0200 +++ docky-2.0.4/Docky/Docky/ConfigurationWindow.cs 2010-05-25 13:12:33.844863402 +0200 @@ -141,6 +141,9 @@ HelpersTileview.IconSize = 48; helper_scroll.AddWithViewport (HelpersTileview); + DockServices.Helpers.HelperInstalled += delegate { + RefreshHelpers (); + }; DockServices.Helpers.HelperUninstalled += delegate { RefreshHelpers (); }; diff -Nru docky-2.0.2/Docky/Docky/DockletTile.cs docky-2.0.4/Docky/Docky/DockletTile.cs --- docky-2.0.2/Docky/Docky/DockletTile.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky/Docky/DockletTile.cs 2010-05-03 07:58:13.407077962 +0200 @@ -92,5 +92,13 @@ UpdateInfo (); } + + public override void Dispose () + { + Addin = null; + Provider = null; + + base.Dispose (); + } } } diff -Nru docky-2.0.2/Docky/Docky/Docky.cs docky-2.0.4/Docky/Docky/Docky.cs --- docky-2.0.2/Docky/Docky/Docky.cs 2010-04-12 15:03:31.793612502 +0200 +++ docky-2.0.4/Docky/Docky/Docky.cs 2010-05-28 22:39:57.586377487 +0200 @@ -20,6 +20,7 @@ using System.ComponentModel; using System.Linq; using System.Text; +using System.Threading; using System.IO; using Mono.Unix; @@ -58,6 +59,7 @@ //Init gtk and GLib related Catalog.Init ("docky", AssemblyInfo.LocaleDirectory); + if (!GLib.Thread.Supported) GLib.Thread.Init (); Gdk.Threads.Init (); NDesk.DBus.BusG.Init (); Gtk.Application.Init ("Docky", ref args); @@ -72,6 +74,9 @@ // set process name DockServices.System.SetProcessName ("docky"); + // cache main thread + SystemService.MainThread = Thread.CurrentThread; + // check compositing CheckComposite (); Gdk.Screen.Default.CompositedChanged += delegate { @@ -119,7 +124,7 @@ "Robert Dyer ", "Chris Szikszoy ", "Rico Tzschichholz ", - "Seif Lofty ", + "Seif Lotfy ", "Chris Halse Rogers ", "Alex Launi " }; diff -Nru docky-2.0.2/Docky/Docky/HelperTile.cs docky-2.0.4/Docky/Docky/HelperTile.cs --- docky-2.0.2/Docky/Docky/HelperTile.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky/Docky/HelperTile.cs 2010-05-25 13:12:33.844863402 +0200 @@ -34,9 +34,7 @@ public HelperTile (Helper helper) { this.Helper = helper; - Helper.HelperStatusChanged += delegate(object sender, HelperStatusChangedEventArgs e) { - SetProps (); - }; + DockServices.Helpers.HelperStatusChanged += HandleHelperHelperStatusChanged; ButtonStateDisabledText = Catalog.GetString ("_Enable"); ButtonStateEnabledText = Catalog.GetString ("_Disable"); @@ -67,7 +65,7 @@ SetProps (); } - + void SetProps () { SubDescriptionText = Helper.IsRunning ? Catalog.GetString ("Running") : Catalog.GetString ("Stopped"); @@ -79,5 +77,18 @@ Helper.Enabled = !Enabled; SetProps (); } + + void HandleHelperHelperStatusChanged (object sender, HelperStatusChangedEventArgs e) + { + SetProps (); + } + + public override void Dispose () + { + DockServices.Helpers.HelperStatusChanged -= HandleHelperHelperStatusChanged; + Helper = null; + + base.Dispose (); + } } } diff -Nru docky-2.0.2/Docky/Docky/Interface/DockWindow.cs docky-2.0.4/Docky/Docky/Interface/DockWindow.cs --- docky-2.0.2/Docky/Docky/Interface/DockWindow.cs 2010-04-11 13:17:19.515355853 +0200 +++ docky-2.0.4/Docky/Docky/Interface/DockWindow.cs 2010-05-25 19:03:05.156114234 +0200 @@ -262,6 +262,10 @@ update_screen_regions = true; SetTooltipVisibility (); + if (background_buffer != null) { + background_buffer.Dispose (); + background_buffer = null; + } AnimatedDraw (); } } @@ -379,8 +383,9 @@ } else if (hoveredItem != null && background_buffer != null) { if (ExternalDragActive) { if (DragTracker.ItemAcceptsDrop ()) { - if (launch_hover_buffer == null) - launch_hover_buffer = DrawHoverText (launch_hover_buffer, Catalog.GetString ("Drop to open")); + if (launch_hover_buffer != null) + launch_hover_buffer.Dispose (); + launch_hover_buffer = DrawHoverText (launch_hover_buffer, hoveredItem.DropText); hover = launch_hover_buffer; } else if (DragTracker.ProviderAcceptsDrop ()) { if (drop_hover_buffer == null) @@ -780,14 +785,16 @@ void HandleMenuHidden (object sender, EventArgs e) { + update_screen_regions = true; SetTooltipVisibility (); AnimatedDraw (); } void HandleMenuShown (object sender, EventArgs e) { - AnimatedDraw (); + update_screen_regions = true; SetTooltipVisibility (); + AnimatedDraw (); } void DockyControllerThemeChanged (object sender, EventArgs e) @@ -1535,7 +1542,7 @@ DockySurface surface = item.IconSurface (main_buffer, IconSize, IconSize, VisibleDockHeight); width = surface.Width; - height = surface.Height; + height = surface.Height; if (item.RotateWithDock && VerticalDock) { int tmp = width; @@ -1798,7 +1805,7 @@ Gdk.Rectangle region = hoverArea; region.X += window_position.X; region.Y += window_position.Y; - if (ConfigurationMode || Painter != null) + if (Menu.Visible || ConfigurationMode || Painter != null) adi.SetScreenRegion (Screen, new Gdk.Rectangle (0, 0, 0, 0)); else adi.SetScreenRegion (Screen, region); @@ -2521,6 +2528,12 @@ background_buffer = new DockySurface (BackgroundWidth, BackgroundHeight, surface); } + if (ConfigurationMode) { + background_buffer.Context.Rectangle (0, 0, BackgroundWidth, BackgroundHeight); + background_buffer.Context.Color = new Cairo.Color (1, 1, 1, 0.10); + background_buffer.Context.Fill (); + } + Gdk.Pixbuf background = DockServices.Drawing.LoadIcon (Docky.Controller.BackgroundSvg); Gdk.Pixbuf tmp; diff -Nru docky-2.0.2/Docky/Docky/Interface/HoverTextManager.cs docky-2.0.4/Docky/Docky/Interface/HoverTextManager.cs --- docky-2.0.2/Docky/Docky/Interface/HoverTextManager.cs 2010-04-12 10:16:35.366114834 +0200 +++ docky-2.0.4/Docky/Docky/Interface/HoverTextManager.cs 2010-05-25 13:38:51.944864182 +0200 @@ -129,8 +129,8 @@ GLib.Source.Remove (timer); Gdk.Rectangle monitor_geo = window.Screen.GetMonitorGeometry (Monitor); - center.X = Math.Max (0, Math.Min (center.X, monitor_geo.X + monitor_geo.Width - surface.Width)); - center.Y = Math.Max (0, Math.Min (center.Y, monitor_geo.Y + monitor_geo.Height - surface.Height)); + center.X = Math.Max (monitor_geo.X, Math.Min (center.X, monitor_geo.X + monitor_geo.Width - surface.Width)); + center.Y = Math.Max (monitor_geo.Y, Math.Min (center.Y, monitor_geo.Y + monitor_geo.Height - surface.Height)); window.QueueDraw (); window.Move (center.X, center.Y); diff -Nru docky-2.0.2/Docky/Docky/Items/DockyItem.cs docky-2.0.4/Docky/Docky/Items/DockyItem.cs --- docky-2.0.2/Docky/Docky/Items/DockyItem.cs 2010-03-31 17:40:13.386291877 +0200 +++ docky-2.0.4/Docky/Docky/Items/DockyItem.cs 2010-05-03 07:58:13.447077888 +0200 @@ -89,7 +89,6 @@ protected override MenuList OnGetMenuItems () { - // intentionally dont inherit MenuList list = new MenuList (); list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("_Settings"), PrefsIcon, (o, a) => ConfigurationWindow.Instance.Show ())); list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("_About"), AboutIcon, (o, a) => Docky.ShowAbout ())); diff -Nru docky-2.0.2/Docky/Docky/Menus/DockItemMenu.cs docky-2.0.4/Docky/Docky/Menus/DockItemMenu.cs --- docky-2.0.2/Docky/Docky/Menus/DockItemMenu.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky/Docky/Menus/DockItemMenu.cs 2010-05-03 07:58:13.457077994 +0200 @@ -145,6 +145,8 @@ { if (Container.Child != null) { foreach (Gtk.Widget widget in (Container.Child as VBox).Children) { + if (widget is MenuItemWidget) + (widget as MenuItemWidget).SelectedChanged -= HandleSelectedChanged; widget.Dispose (); widget.Destroy (); } @@ -194,16 +196,20 @@ } } vbox.SetSizeRequest (width, -1); - + Container.ShowAll (); } public override void Dispose () { - if (Container != null && Container.Child != null && (Container.Child as VBox).Children != null) - foreach (Gtk.Widget widget in (Container.Child as VBox).Children) + if (Container != null && Container.Child != null && (Container.Child as VBox).Children != null) { + foreach (Gtk.Widget widget in (Container.Child as VBox).Children) { if (widget is MenuItemWidget) (widget as MenuItemWidget).SelectedChanged -= HandleSelectedChanged; + widget.Dispose (); + widget.Destroy (); + } + } base.Dispose (); } diff -Nru docky-2.0.2/Docky/Docky/Menus/DockMenu.cs docky-2.0.4/Docky/Docky/Menus/DockMenu.cs --- docky-2.0.2/Docky/Docky/Menus/DockMenu.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky/Docky/Menus/DockMenu.cs 2010-05-25 13:36:37.414864120 +0200 @@ -278,14 +278,14 @@ case DockPosition.Bottom: case DockPosition.Top: y = oldY; - x = Math.Max (0, Math.Min (oldX, monitor_geo.X + monitor_geo.Width - allocation.Width)); + x = Math.Max (monitor_geo.X, Math.Min (oldX, monitor_geo.X + monitor_geo.Width - allocation.Width)); tailOffset = x - oldX; break; case DockPosition.Left: case DockPosition.Right: x = oldX; - y = Math.Max (0, Math.Min (oldY, monitor_geo.Y + monitor_geo.Height - allocation.Height)); + y = Math.Max (monitor_geo.Y, Math.Min (oldY, monitor_geo.Y + monitor_geo.Height - allocation.Height)); tailOffset = y - oldY; // rotation breaks this diff -Nru docky-2.0.2/Docky/Docky/Menus/MenuItemWidget.cs docky-2.0.4/Docky/Docky/Menus/MenuItemWidget.cs --- docky-2.0.2/Docky/Docky/Menus/MenuItemWidget.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky/Docky/Menus/MenuItemWidget.cs 2010-05-03 07:58:13.467077865 +0200 @@ -296,9 +296,18 @@ { if (icon_surface != null) icon_surface.Dispose (); + icon_surface = null; if (emblem_surface != null) emblem_surface.Dispose (); + emblem_surface = null; + + item.IconChanged -= ItemIconChanged; + item.TextChanged -= ItemTextChanged; + item.DisabledChanged -= ItemDisabledChanged; + item.Dispose (); + item = null; + base.Dispose (); } } diff -Nru docky-2.0.2/Docky/gtk-gui/Docky.ConfigurationWindow.cs docky-2.0.4/Docky/gtk-gui/Docky.ConfigurationWindow.cs --- docky-2.0.2/Docky/gtk-gui/Docky.ConfigurationWindow.cs 2010-04-12 13:47:18.597361676 +0200 +++ docky-2.0.4/Docky/gtk-gui/Docky.ConfigurationWindow.cs 2010-05-25 16:46:27.224863310 +0200 @@ -445,8 +445,8 @@ if ((this.Child != null)) { this.Child.ShowAll(); } - this.DefaultWidth = 449; - this.DefaultHeight = 482; + this.DefaultWidth = 420; + this.DefaultHeight = 430; this.label3.MnemonicWidget = this.theme_combo; this.Show(); this.config_notebook.SwitchPage += new Gtk.SwitchPageHandler(this.OnPageSwitch); diff -Nru docky-2.0.2/Docky/gtk-gui/gui.stetic docky-2.0.4/Docky/gtk-gui/gui.stetic --- docky-2.0.2/Docky/gtk-gui/gui.stetic 2010-04-12 13:46:12.573612075 +0200 +++ docky-2.0.4/Docky/gtk-gui/gui.stetic 2010-05-25 16:46:27.224863310 +0200 @@ -336,7 +336,7 @@ - + Docky Configuration stock:gtk-preferences Menu diff -Nru docky-2.0.2/Docky.DBus/Docky.DBus/DockyDBusItem.cs docky-2.0.4/Docky.DBus/Docky.DBus/DockyDBusItem.cs --- docky-2.0.2/Docky.DBus/Docky.DBus/DockyDBusItem.cs 2010-04-12 09:20:24.483611125 +0200 +++ docky-2.0.4/Docky.DBus/Docky.DBus/DockyDBusItem.cs 2010-05-03 07:58:26.395827942 +0200 @@ -87,7 +87,7 @@ uint number; do { - // should we ever get 100,000 items in here, I hope we crash, though we will likely get an infinite loop + //FIXME should we ever get 100,000 items in here, I hope we crash, though we will likely get an infinite loop number = (uint) rand.Next (0, 100000); } while (known_ids.BinarySearch (number) >= 0); @@ -216,7 +216,7 @@ items[id] = entry; update_time[id] = DateTime.UtcNow; - //Insert items into list... this is stupid but whatever fix later + //TODO Insert items into list... this is stupid but whatever fix later foreach (MenuItem item in items.Values) owner.RemoteMenuItems.Remove (item); @@ -262,6 +262,8 @@ if (items.ContainsKey (item)) { RemoteMenuEntry entry = items[item]; + entry.Clicked -= HandleActivated; + items.Remove (item); owner.RemoteMenuItems.Remove (entry); @@ -332,13 +334,24 @@ if (MenuItemActivated != null) MenuItemActivated ((sender as RemoteMenuEntry).ID); } + #region IDisposable implementation public void Dispose () { if (timer > 0) GLib.Source.Remove (timer); + + known_ids.Clear (); + update_time.Clear (); + + foreach (RemoteMenuEntry m in items.Values) { + m.Clicked -= HandleActivated; + m.Dispose (); + } + items.Clear (); + + owner = null; } - #endregion } } diff -Nru docky-2.0.2/Docky.Items/Docky.Items/AbstractDockItem.cs docky-2.0.4/Docky.Items/Docky.Items/AbstractDockItem.cs --- docky-2.0.2/Docky.Items/Docky.Items/AbstractDockItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Items/AbstractDockItem.cs 2010-05-25 19:03:05.156114234 +0200 @@ -26,6 +26,8 @@ using Gdk; using Gtk; +using Mono.Unix; + using Docky; using Docky.CairoHelper; using Docky.Painters; @@ -111,6 +113,13 @@ } /// + /// The hover text shown when this item can accept a drop + /// + public virtual string DropText { + get { return string.Format (Catalog.GetString ("Drop to open with {0}"), HoverText); } + } + + /// /// The animation with which the item wishes to display /// public ClickAnimation ClickAnimation { @@ -634,69 +643,71 @@ if (string.IsNullOrEmpty (BadgeText)) return; - Pango.Layout layout = DockServices.Drawing.ThemedPangoLayout (); - layout.Width = Pango.Units.FromPixels (surface.Height / 2); - layout.Ellipsize = Pango.EllipsizeMode.None; - layout.FontDescription = new Gtk.Style().FontDescription; - layout.FontDescription.Weight = Pango.Weight.Bold; - - Pango.Rectangle inkRect, logicalRect; - int tsize = 3; - do { - layout.FontDescription.AbsoluteSize = Pango.Units.FromPixels (tsize); - layout.SetText (BadgeText); - layout.GetPixelExtents (out inkRect, out logicalRect); - tsize++; - } while (Math.Max (logicalRect.Width, logicalRect.Height) < surface.Height / (IsSmall ? 1 : 2) - 8); - - int size = Math.Max (logicalRect.Width, logicalRect.Height); - int padding = 4; - int lineWidth = 2; - int x = surface.Width - size / 2 - padding - lineWidth; - int y = size / 2 + padding + lineWidth; - - if (!IsSmall) { - // draw outline shadow - surface.Context.LineWidth = lineWidth; - surface.Context.Color = new Cairo.Color (0, 0, 0, 0.5); - surface.Context.Arc (x, y + 1, size / 2 + padding, 0, Math.PI * 2); - surface.Context.Stroke (); - - // draw filled gradient - RadialGradient rg = new RadialGradient (x, lineWidth, 0, x, lineWidth, size + 2 * padding); - rg.AddColorStop (0, badgeColors [0]); - rg.AddColorStop (1.0, badgeColors [1]); + using (Pango.Layout layout = DockServices.Drawing.ThemedPangoLayout ()) + { + layout.Width = Pango.Units.FromPixels (surface.Height / 2); + layout.Ellipsize = Pango.EllipsizeMode.None; + layout.FontDescription = new Gtk.Style ().FontDescription; + layout.FontDescription.Weight = Pango.Weight.Bold; - surface.Context.Pattern = rg; - surface.Context.Arc (x, y, size / 2 + padding, 0, Math.PI * 2); - surface.Context.Fill (); - rg.Destroy (); + Pango.Rectangle inkRect, logicalRect; + int tsize = 3; + do { + layout.FontDescription.AbsoluteSize = Pango.Units.FromPixels (tsize); + layout.SetText (BadgeText); + layout.GetPixelExtents (out inkRect, out logicalRect); + tsize++; + } while (Math.Max (logicalRect.Width, logicalRect.Height) < surface.Height / (IsSmall ? 1 : 2) - 8); + + int size = Math.Max (logicalRect.Width, logicalRect.Height); + int padding = 4; + int lineWidth = 2; + int x = surface.Width - size / 2 - padding - lineWidth; + int y = size / 2 + padding + lineWidth; + + if (!IsSmall) { + // draw outline shadow + surface.Context.LineWidth = lineWidth; + surface.Context.Color = new Cairo.Color (0, 0, 0, 0.5); + surface.Context.Arc (x, y + 1, size / 2 + padding, 0, Math.PI * 2); + surface.Context.Stroke (); + + // draw filled gradient + RadialGradient rg = new RadialGradient (x, lineWidth, 0, x, lineWidth, size + 2 * padding); + rg.AddColorStop (0, badgeColors [0]); + rg.AddColorStop (1.0, badgeColors [1]); + + surface.Context.Pattern = rg; + surface.Context.Arc (x, y, size / 2 + padding, 0, Math.PI * 2); + surface.Context.Fill (); + rg.Destroy (); + + // draw outline + surface.Context.Color = new Cairo.Color (1, 1, 1, 1); + surface.Context.Arc (x, y, size / 2 + padding, 0, Math.PI * 2); + surface.Context.Stroke (); + + surface.Context.LineWidth = lineWidth / 2; + surface.Context.Color = badgeColors [1]; + surface.Context.Arc (x, y, size / 2 + padding - lineWidth, 0, Math.PI * 2); + surface.Context.Stroke (); + + surface.Context.Color = new Cairo.Color (0, 0, 0, 0.2); + } else { + x = surface.Width - logicalRect.Width / 2; + y = logicalRect.Height / 2; + surface.Context.Color = new Cairo.Color (0, 0, 0, 0.6); + } - // draw outline - surface.Context.Color = new Cairo.Color (1, 1, 1, 1); - surface.Context.Arc (x, y, size / 2 + padding, 0, Math.PI * 2); - surface.Context.Stroke (); + // draw text + surface.Context.MoveTo (x - logicalRect.Width / 2, y - logicalRect.Height / 2); - surface.Context.LineWidth = lineWidth / 2; - surface.Context.Color = badgeColors [1]; - surface.Context.Arc (x, y, size / 2 + padding - lineWidth, 0, Math.PI * 2); - surface.Context.Stroke (); - - surface.Context.Color = new Cairo.Color (0, 0, 0, 0.2); - } else { - x = surface.Width - logicalRect.Width / 2; - y = logicalRect.Height / 2; - surface.Context.Color = new Cairo.Color (0, 0, 0, 0.6); - } - - // draw text - surface.Context.MoveTo (x - logicalRect.Width / 2, y - logicalRect.Height / 2); - - Pango.CairoHelper.LayoutPath (surface.Context, layout); - surface.Context.LineWidth = 2; - surface.Context.StrokePreserve (); - surface.Context.Color = new Cairo.Color (1, 1, 1, 1); - surface.Context.Fill (); + Pango.CairoHelper.LayoutPath (surface.Context, layout); + surface.Context.LineWidth = 2; + surface.Context.StrokePreserve (); + surface.Context.Color = new Cairo.Color (1, 1, 1, 1); + surface.Context.Fill (); + } } /// @@ -718,32 +729,31 @@ if (text_buffer == null) { - Pango.Layout layout = DockServices.Drawing.ThemedPangoLayout (); - - layout.FontDescription = style.FontDescription; - layout.FontDescription.AbsoluteSize = Pango.Units.FromPixels (11); - layout.FontDescription.Weight = Pango.Weight.Bold; - layout.Ellipsize = Pango.EllipsizeMode.End; - layout.Width = Pango.Units.FromPixels (500); - - layout.SetText (HoverText); - - Pango.Rectangle inkRect, logicalRect; - layout.GetPixelExtents (out inkRect, out logicalRect); - - int textWidth = inkRect.Width; - int textHeight = logicalRect.Height; - int buffer = HoverTextHeight - textHeight; - text_buffer = new DockySurface (Math.Max (HoverTextHeight, textWidth + buffer), HoverTextHeight, model); - - Cairo.Context cr = text_buffer.Context; - - cr.MoveTo ((text_buffer.Width - textWidth) / 2, buffer / 2); - Pango.CairoHelper.LayoutPath (cr, layout); - cr.Color = isLight ? new Cairo.Color (0.1, 0.1, 0.1) : new Cairo.Color (1, 1, 1); - cr.Fill (); - - layout.Dispose (); + using (Pango.Layout layout = DockServices.Drawing.ThemedPangoLayout ()) + { + layout.FontDescription = style.FontDescription; + layout.FontDescription.AbsoluteSize = Pango.Units.FromPixels (11); + layout.FontDescription.Weight = Pango.Weight.Bold; + layout.Ellipsize = Pango.EllipsizeMode.End; + layout.Width = Pango.Units.FromPixels (500); + + layout.SetText (HoverText); + + Pango.Rectangle inkRect, logicalRect; + layout.GetPixelExtents (out inkRect, out logicalRect); + + int textWidth = inkRect.Width; + int textHeight = logicalRect.Height; + int buffer = HoverTextHeight - textHeight; + text_buffer = new DockySurface (Math.Max (HoverTextHeight, textWidth + buffer), HoverTextHeight, model); + + Cairo.Context cr = text_buffer.Context; + + cr.MoveTo ((text_buffer.Width - textWidth) / 2, buffer / 2); + Pango.CairoHelper.LayoutPath (cr, layout); + cr.Color = isLight ? new Cairo.Color (0.1, 0.1, 0.1) : new Cairo.Color (1, 1, 1); + cr.Fill (); + } } return text_buffer; diff -Nru docky-2.0.2/Docky.Items/Docky.Items/ApplicationDockItem.cs docky-2.0.4/Docky.Items/Docky.Items/ApplicationDockItem.cs --- docky-2.0.2/Docky.Items/Docky.Items/ApplicationDockItem.cs 2010-04-12 09:19:52.873612208 +0200 +++ docky-2.0.4/Docky.Items/Docky.Items/ApplicationDockItem.cs 2010-05-25 13:12:03.948613925 +0200 @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.IO; using System.Linq; using System.Text; using System.Threading; @@ -142,6 +143,12 @@ Windows = Enumerable.Empty (); } + public void RecollectWindows () + { + UpdateWindows (); + OnPaintNeeded (); + } + protected override MenuList OnGetMenuItems () { MenuList list = base.OnGetMenuItems (); diff -Nru docky-2.0.2/Docky.Items/Docky.Items/FileApplicationProvider.cs docky-2.0.4/Docky.Items/Docky.Items/FileApplicationProvider.cs --- docky-2.0.2/Docky.Items/Docky.Items/FileApplicationProvider.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Items/FileApplicationProvider.cs 2010-05-26 11:04:15.356739321 +0200 @@ -79,6 +79,10 @@ } } + Wnck.Window prevActive = null; + + bool longMatchInProgress = false; + public FileApplicationProvider () { items = new Dictionary (); @@ -89,48 +93,95 @@ // update the transient items when something happens in a desktop file directory // It is possible that a .desktop file was created for a window that didn't have one before, // this would associate that desktop file with the existing window. - WindowMatcher.DesktopFileChanged += delegate { - UpdateTransientItems (); - }; + WindowMatcher.DesktopFileChanged += HandleWindowMatcherDesktopFileChanged; Wnck.Screen.Default.WindowOpened += WnckScreenDefaultWindowOpened; Wnck.Screen.Default.WindowClosed += WnckScreenDefaultWindowClosed; - Wnck.Screen.Default.ViewportsChanged += WnckScreenDefaultViewportsChanged; - Wnck.Screen.Default.ActiveWorkspaceChanged += WnckScreenDefaultActiveWorkspaceChanged; + + if (WnckDockItem.CurrentDesktopOnly) { + Wnck.Screen.Default.ViewportsChanged += WnckScreenDefaultViewportsChanged; + Wnck.Screen.Default.ActiveWorkspaceChanged += WnckScreenDefaultActiveWorkspaceChanged; + Wnck.Screen.Default.ActiveWindowChanged += WnckScreenDefaultActiveWindowChanged; + prevActive = Wnck.Screen.Default.ActiveWindow; + if (prevActive != null) + prevActive.GeometryChanged += HandleActiveWindowGeometryChangedChanged; + } } - + + #region CurrentDesktopOnly + + void WnckScreenDefaultActiveWindowChanged (object o, ActiveWindowChangedArgs args) + { + if (prevActive != null) + prevActive.GeometryChanged -= HandleActiveWindowGeometryChangedChanged; + prevActive = Wnck.Screen.Default.ActiveWindow; + if (prevActive != null) + prevActive.GeometryChanged += HandleActiveWindowGeometryChangedChanged; + UpdateTransientItems (); + } + + void HandleActiveWindowGeometryChangedChanged (object o, EventArgs args) + { + UpdateTransientItems (); + } + void WnckScreenDefaultActiveWorkspaceChanged (object o, ActiveWorkspaceChangedArgs args) { UpdateTransientItems (); } - + void WnckScreenDefaultViewportsChanged (object o, EventArgs args) { UpdateTransientItems (); } + #endregion + + void HandleWindowMatcherDesktopFileChanged (object sender, DesktopFileChangedEventArgs e) + { + UpdateTransientItems (); + } + void WnckScreenDefaultWindowOpened (object o, WindowOpenedArgs args) { if (args.Window.IsSkipTasklist) return; - if (!WindowMatcher.Default.WindowIsReadyForMatch (args.Window)) { - int i = 0; - // try to give open office enough time to open and set its title - GLib.Timeout.Add (150, delegate { - if (!WindowMatcher.Default.WindowIsReadyForMatch (args.Window) && i < 20) { - i++; - return true; - } - UpdateTransientItems (); - return false; - }); - } else { - // ensure we run last (more or less) so that all icons can update first - GLib.Timeout.Add (150, delegate { + longMatchInProgress = !WindowMatcher.Default.WindowIsReadyForMatch (args.Window); + + // ensure we run last (more or less) so that all icons can update first + GLib.Timeout.Add (150, delegate { + if (WindowMatcher.Default.WindowIsReadyForMatch (args.Window)) { + longMatchInProgress = false; UpdateTransientItems (); - return false; - }); + } else { + // handle applications which set their proper (matchable) window title very late, + // their windows will be monitored for name changes (give up after 5 seconds) + uint matching_timeout = 5000; + // wait for OpenOffice up to 1min to startup before giving up + if (WindowMatcher.Default.WindowIsOpenOffice (args.Window)) + matching_timeout = 60000; + args.Window.NameChanged += HandleUnmatchedWindowNameChanged; + GLib.Timeout.Add (matching_timeout, delegate { + if (!WindowMatcher.Default.WindowIsReadyForMatch (args.Window)) { + args.Window.NameChanged -= HandleUnmatchedWindowNameChanged; + longMatchInProgress = false; + UpdateTransientItems (); + } + return false; + }); + } + return false; + }); + } + + void HandleUnmatchedWindowNameChanged (object sender, EventArgs e) + { + Wnck.Window window = (sender as Wnck.Window); + if (WindowMatcher.Default.WindowIsReadyForMatch (window)) { + window.NameChanged -= HandleUnmatchedWindowNameChanged; + longMatchInProgress = false; + UpdateTransientItems (); } } @@ -157,6 +208,10 @@ } return; } + + if (longMatchInProgress) + return; + // we will need a list of these bad boys we can mess with List windows = UnmanagedWindows.ToList (); @@ -172,6 +227,19 @@ desktopFile = WindowMatcher.Default.DesktopFileForWindow (window); if (!string.IsNullOrEmpty (desktopFile)) { + //This fixes WindowMatching for OpenOffice which is a bit slow setting up its window title + //Check if a existing ApplicationDockItem already uses this DesktopItem + ApplicationDockItem appdi; + if ((appdi = transient_items + .Where (adi => (adi is ApplicationDockItem && (adi as ApplicationDockItem).OwnedItem.Location == desktopFile)) + .Cast () + .FirstOrDefault ()) != null) { + + //Try again to gain this missing window + appdi.RecollectWindows (); + continue; + } + item = ApplicationDockItem.NewFromUri (new Uri (desktopFile).AbsoluteUri); } else { item = new WindowDockItem (window); @@ -196,6 +264,8 @@ removed_transient_items.Add (wdi); continue; } + if (!wdi.ManagedWindows.Any ()) + removed_transient_items.Add (wdi); } RemoveTransientItems (removed_transient_items); @@ -273,6 +343,7 @@ public void PinToDock (ApplicationDockItem item) { + item.WindowsChanged -= HandleTransientWindowsChanged; transient_items.Remove (item); items.Add (new Uri (item.OwnedItem.Location).AbsoluteUri, item); @@ -361,10 +432,18 @@ public override void Dispose () { + WindowMatcher.DesktopFileChanged -= HandleWindowMatcherDesktopFileChanged; + Wnck.Screen.Default.WindowOpened -= WnckScreenDefaultWindowOpened; Wnck.Screen.Default.WindowClosed -= WnckScreenDefaultWindowClosed; - Wnck.Screen.Default.ViewportsChanged -= WnckScreenDefaultViewportsChanged; - Wnck.Screen.Default.ActiveWorkspaceChanged -= WnckScreenDefaultActiveWorkspaceChanged; + + if (WnckDockItem.CurrentDesktopOnly) { + Wnck.Screen.Default.ViewportsChanged -= WnckScreenDefaultViewportsChanged; + Wnck.Screen.Default.ActiveWorkspaceChanged -= WnckScreenDefaultActiveWorkspaceChanged; + Wnck.Screen.Default.ActiveWindowChanged -= WnckScreenDefaultActiveWindowChanged; + if (prevActive != null) + prevActive.GeometryChanged -= HandleActiveWindowGeometryChangedChanged; + } IEnumerable old_items = Items; diff -Nru docky-2.0.2/Docky.Items/Docky.Items/FileDockItem.cs docky-2.0.4/Docky.Items/Docky.Items/FileDockItem.cs --- docky-2.0.2/Docky.Items/Docky.Items/FileDockItem.cs 2010-04-11 08:04:53.557856122 +0200 +++ docky-2.0.4/Docky.Items/Docky.Items/FileDockItem.cs 2010-05-25 19:03:05.156114234 +0200 @@ -1,5 +1,5 @@ // -// Copyright (C) 2009 Jason Smith, Robert Dyer +// Copyright (C) 2009 Jason Smith, Robert Dyer, Chris Szikszoy // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using IO = System.IO; using System.Linq; using System.Text; @@ -34,20 +35,21 @@ { public static FileDockItem NewFromUri (string uri) { - // FIXME: need to do something with this... .Exists will fail for non native files - // but they are still valid file items (like an unmounted ftp://... file) - // even File.QueryExists () will return false for valid files (ftp://) that aren't mounted. - /* - string path = Gnome.Vfs.Global.GetLocalPathFromUri (uri); - if (!Directory.Exists (path) && !File.Exists (path)) { - return null; - } - */ - return new FileDockItem (uri); + return NewFromUri (uri, null, null); } public static FileDockItem NewFromUri (string uri, string force_hover_text, string backup_icon) { + // FIXME: need to do something with this... .Exists will fail for non native files + // but they are still valid file items (like an unmounted ftp://... file) + // even File.QueryExists () will return false for valid files (ftp://) that aren't mounted. + + // for now we just attempt to figure out if it is a local file and check for its existance + if (uri.IndexOf ("file://") != -1 || uri.IndexOf ("://") == -1) { + string path = Gnome.Vfs.Global.GetLocalPathFromUri (uri); + if (!IO.Directory.Exists (path) && !IO.File.Exists (path)) + return null; + } return new FileDockItem (uri, force_hover_text, backup_icon); } @@ -56,6 +58,7 @@ const string FilesystemFreeKey = "filesystem::free"; const string CustomIconKey = "metadata::custom-icon"; const string EmblemsKey = "metadata::emblems"; + string uri; bool is_folder; string forced_hover_text; @@ -67,6 +70,10 @@ public File OwnedFile { get; private set; } + public override string DropText { + get { return string.Format (Catalog.GetString ("Drop to move to {0}"), HoverText); } + } + protected FileDockItem (string uri) { this.uri = uri; @@ -155,15 +162,15 @@ protected override bool OnCanAcceptDrop (IEnumerable uris) { - bool can_write; - // this could fail if we try to call it on an unmounted location + bool can_write = false; + try { - can_write = OwnedFile.QueryInfo ("access::can-write"); + if (!string.IsNullOrEmpty (OwnedFile.Path)) + can_write = OwnedFile.QueryInfo ("access::can-write"); } catch { - can_write = false; } - // only accept the drop if it's a folder, and we can write to it. + // only accept the drop if it's a folder, and we can write to it return is_folder && can_write; } diff -Nru docky-2.0.2/Docky.Items/Docky.Items/IconDockItem.cs docky-2.0.4/Docky.Items/Docky.Items/IconDockItem.cs --- docky-2.0.2/Docky.Items/Docky.Items/IconDockItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Items/IconDockItem.cs 2010-05-03 07:58:26.415827955 +0200 @@ -99,15 +99,19 @@ Emblems.RemoveAll (e => e.Position == emblem.Position); // add the new emblem Emblems.Add (emblem); + emblem.Changed += HandleEmblemChanged; + QueueRedraw (); + } + + void HandleEmblemChanged (object sender, EventArgs e) + { QueueRedraw (); - emblem.Changed += delegate { - QueueRedraw (); - }; } public void RemoveEmblem (IconEmblem emblem) { if (Emblems.Contains (emblem)) { + emblem.Changed -= HandleEmblemChanged; Emblems.Remove (emblem); QueueRedraw (); } @@ -188,5 +192,21 @@ if (IconUpdated != null) IconUpdated (this, EventArgs.Empty); } + + public override void Dispose () + { + if (Emblems.Any ()) + Emblems.ForEach (emblem => { + emblem.Changed -= HandleEmblemChanged; + emblem.Dispose (); + }); + Emblems.Clear (); + + if (forced_pixbuf != null) + forced_pixbuf.Dispose (); + forced_pixbuf = null; + + base.Dispose (); + } } } diff -Nru docky-2.0.2/Docky.Items/Docky.Items/IconEmblem.cs docky-2.0.4/Docky.Items/Docky.Items/IconEmblem.cs --- docky-2.0.2/Docky.Items/Docky.Items/IconEmblem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Items/IconEmblem.cs 2010-05-03 07:58:13.257077995 +0200 @@ -118,5 +118,12 @@ if (Changed != null) Changed (this, EventArgs.Empty); } + + public void Dispose () + { + if (forced_pixbuf != null) + forced_pixbuf.Dispose (); + forced_pixbuf = null; + } } } diff -Nru docky-2.0.2/Docky.Items/Docky.Items/WindowDockItem.cs docky-2.0.4/Docky.Items/Docky.Items/WindowDockItem.cs --- docky-2.0.2/Docky.Items/Docky.Items/WindowDockItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Items/WindowDockItem.cs 2010-05-03 07:58:13.257077995 +0200 @@ -98,5 +98,13 @@ Windows = Enumerable.Empty (); } } + + public override void Dispose () + { + Wnck.Screen.Default.WindowOpened -= WnckScreenDefaultWindowOpened; + Wnck.Screen.Default.WindowClosed -= WnckScreenDefaultWindowClosed; + + base.Dispose (); + } } } diff -Nru docky-2.0.2/Docky.Items/Docky.Items/WnckDockItem.cs docky-2.0.4/Docky.Items/Docky.Items/WnckDockItem.cs --- docky-2.0.2/Docky.Items/Docky.Items/WnckDockItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Items/WnckDockItem.cs 2010-05-25 17:05:21.604866094 +0200 @@ -63,12 +63,23 @@ } } + static bool? currentDesktop; + public static bool CurrentDesktopOnly { + get { + if (!currentDesktop.HasValue) + currentDesktop = prefs.Get ("CurrentDesktopOnly", false); + return currentDesktop.Value; + } + } + public IEnumerable ManagedWindows { get { - if (prefs.Get ("CurrentDesktopOnly", false)) - return Windows.Where (w => !w.IsSkipTasklist && w.Workspace != null && Wnck.Screen.Default.ActiveWorkspace != null && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)); - else - return Windows.Where (w => !w.IsSkipTasklist); + return Windows.Where (w => !w.IsSkipTasklist && + (!CurrentDesktopOnly + || (w.Workspace != null + && Wnck.Screen.Default.ActiveWorkspace != null + && w.IsInViewport (Wnck.Screen.Default.ActiveWorkspace)) + )); } } diff -Nru docky-2.0.2/Docky.Items/Docky.Menus/IconMenuItem.cs docky-2.0.4/Docky.Items/Docky.Menus/IconMenuItem.cs --- docky-2.0.2/Docky.Items/Docky.Menus/IconMenuItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Menus/IconMenuItem.cs 2010-05-03 07:58:13.267078062 +0200 @@ -46,6 +46,7 @@ Clicked += onClicked; } #endregion + #region pixbuf icon constructors public IconMenuItem (string text, Pixbuf icon, bool disabled) : this (text, "", disabled) { diff -Nru docky-2.0.2/Docky.Items/Docky.Menus/MenuItem.cs docky-2.0.4/Docky.Items/Docky.Menus/MenuItem.cs --- docky-2.0.2/Docky.Items/Docky.Menus/MenuItem.cs 2010-03-31 17:41:09.157534354 +0200 +++ docky-2.0.4/Docky.Items/Docky.Menus/MenuItem.cs 2010-05-03 07:58:13.296741603 +0200 @@ -27,7 +27,7 @@ namespace Docky.Menus { - public class MenuItem + public class MenuItem : IDisposable { public event EventHandler DisabledChanged; public event EventHandler TextChanged; @@ -152,5 +152,19 @@ { Clicked += onClicked; } + + #region IDisposable implementation + public void Dispose () + { + if (forced_pixbuf != null) + forced_pixbuf.Dispose (); + forced_pixbuf = null; + + Clicked = null; + IconChanged = null; + DisabledChanged = null; + TextChanged = null; + } + #endregion } } diff -Nru docky-2.0.2/Docky.Items/Docky.Menus/MenuList.cs docky-2.0.4/Docky.Items/Docky.Menus/MenuList.cs --- docky-2.0.2/Docky.Items/Docky.Menus/MenuList.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Menus/MenuList.cs 2010-05-03 07:58:13.307077634 +0200 @@ -33,7 +33,7 @@ Footer, } - public class MenuList + public class MenuList : IDisposable { Dictionary> list; Dictionary titles; @@ -126,5 +126,17 @@ return result; } + + #region IDisposable implementation + public void Dispose () + { + foreach (List sublist in list.Values) + sublist.Clear (); + list.Clear (); + titles.Clear (); + list = null; + titles = null; + } + #endregion } } diff -Nru docky-2.0.2/Docky.Items/Docky.Painters/PagingDockPainter.cs docky-2.0.4/Docky.Items/Docky.Painters/PagingDockPainter.cs --- docky-2.0.2/Docky.Items/Docky.Painters/PagingDockPainter.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Items/Docky.Painters/PagingDockPainter.cs 2010-05-03 07:58:13.315826960 +0200 @@ -258,8 +258,7 @@ { lock (buffers) { for (int i = 0; i < buffers.Length; i++) - if (buffers [i] != null) - { + if (buffers [i] != null) { buffers [i].Dispose (); buffers [i] = null; } diff -Nru docky-2.0.2/Docky.Services/AssemblyInfo.cs docky-2.0.4/Docky.Services/AssemblyInfo.cs --- docky-2.0.2/Docky.Services/AssemblyInfo.cs 2010-04-12 15:07:34.287361503 +0200 +++ docky-2.0.4/Docky.Services/AssemblyInfo.cs 2010-05-31 08:00:18.374371776 +0200 @@ -50,8 +50,8 @@ { internal static class AssemblyInfo { - public const string DisplayVersion = "2.0.2"; - public const string VersionDetails = "bzr docky-2.0 r1210"; + public const string DisplayVersion = "2.0.4"; + public const string VersionDetails = "bzr docky-2.0 r1266"; public const string LocaleDirectory = "/usr/share/locale"; public const string DataDirectory = "/usr/share"; } diff -Nru docky-2.0.2/Docky.Services/Docky.Services/DockServices.cs docky-2.0.4/Docky.Services/Docky.Services/DockServices.cs --- docky-2.0.2/Docky.Services/Docky.Services/DockServices.cs 2010-04-12 15:03:31.793612502 +0200 +++ docky-2.0.4/Docky.Services/Docky.Services/DockServices.cs 2010-05-25 13:12:33.844863402 +0200 @@ -1,5 +1,5 @@ // -// Copyright (C) 2009 Jason Smith +// Copyright (C) 2009 Jason Smith, Robert Dyer // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -19,8 +19,6 @@ namespace Docky.Services { - - public class DockServices { public static DrawingService Drawing { get; private set; } @@ -48,6 +46,7 @@ public static void Dispose () { System.Dispose (); + Helpers.Dispose (); } } } diff -Nru docky-2.0.2/Docky.Services/Docky.Services/Helper.cs docky-2.0.4/Docky.Services/Docky.Services/Helper.cs --- docky-2.0.2/Docky.Services/Docky.Services/Helper.cs 2010-04-11 08:04:53.597855806 +0200 +++ docky-2.0.4/Docky.Services/Docky.Services/Helper.cs 2010-05-25 13:22:35.008613981 +0200 @@ -1,5 +1,5 @@ // -// Copyright (C) 2009 Chris Szikszoy +// Copyright (C) 2009 Chris Szikszoy, Robert Dyer // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -22,14 +22,13 @@ namespace Docky.Services { - public class Helper { public File File { get; private set; } + public HelperMetadata Data { get; private set; } - public bool IsUser { get; private set; } - uint alive_timer = 0; + public bool IsUser { get; private set; } bool? is_running; public bool IsRunning { @@ -45,6 +44,7 @@ OnHelperStatusChanged (); } } + public bool Enabled { get { return prefs.Get (prefs.SanitizeKey (File.Basename), false); @@ -63,19 +63,18 @@ } } - static IPreferences prefs; + static IPreferences prefs = DockServices.Preferences.Get (); + Diag.Process Proc { get; set; } - uint X_PERM = Convert.ToUInt32 ("1001001", 2); - // interested parties should not listen for this event - // instead use the ScriptStatusChanged event from ScriptService - public event EventHandler HelperStatusChanged; + readonly uint X_PERM = Convert.ToUInt32 ("1001001", 2); + + internal event EventHandler HelperStatusChanged; public Helper (File file) { - prefs = DockServices.Preferences.Get (); - this.File = file; - this.IsUser = file.Path.StartsWith ("/home/"); + File = file; + IsUser = file.Path.StartsWith ("/home/"); GLib.File DataFile; if (IsUser) @@ -100,14 +99,17 @@ void Start () { + if (Proc != null) + return; + // if the execute bits aren't set, try to set if (!File.QueryInfo ("access::can-execute")) { Log.Debug ("Execute permissions are not currently set for '{0}', attempting to set them.", File.Path); - uint currentPerm = File.QueryInfo ("unix::mode"); try { + uint currentPerm = File.QueryInfo ("unix::mode"); File.SetAttributeUint32 ("unix::mode", currentPerm | X_PERM, 0, null); - // if we can't log the error, and disable this script } catch (Exception e) { + // if we can't set execute, then log the error and disable this script Log.Error ("Failed to set execute permissions for '{0}': {1}", File.Path, e.Message); Enabled = false; return; @@ -115,56 +117,74 @@ } Log.Info ("Starting {0}", File.Basename); - if (Proc == null) { - Proc = new Diag.Process (); - Proc.StartInfo.FileName = File.Path; - Proc.StartInfo.UseShellExecute = false; - Proc.StartInfo.RedirectStandardError = true; - Proc.StartInfo.RedirectStandardOutput = true; - Proc.EnableRaisingEvents = true; - Proc.ErrorDataReceived += delegate(object sender, Diag.DataReceivedEventArgs e) { - if (DockServices.Helpers.ShowOutput && !string.IsNullOrEmpty (e.Data)) - Log.Error ("{0} :: {1}", File.Basename, e.Data); - }; - Proc.OutputDataReceived += delegate(object sender, Diag.DataReceivedEventArgs e) { - if (DockServices.Helpers.ShowOutput && !string.IsNullOrEmpty (e.Data)) - Log.Info ("{0} :: {1}", File.Basename, e.Data); - }; - Proc.Exited += delegate { - IsRunning = false; - Log.Info ("{0} has exited (Code {1}).", File.Basename, Proc.ExitCode); - }; - } - + + Proc = new Diag.Process (); + Proc.StartInfo.FileName = File.Path; + Proc.StartInfo.UseShellExecute = false; + Proc.StartInfo.RedirectStandardError = true; + Proc.StartInfo.RedirectStandardOutput = true; + Proc.EnableRaisingEvents = true; + Proc.ErrorDataReceived += delegate(object sender, Diag.DataReceivedEventArgs e) { + if (DockServices.Helpers.ShowOutput && !string.IsNullOrEmpty (e.Data)) + Log.Error ("{0} :: {1}", File.Basename, e.Data); + }; + Proc.OutputDataReceived += delegate(object sender, Diag.DataReceivedEventArgs e) { + if (DockServices.Helpers.ShowOutput && !string.IsNullOrEmpty (e.Data)) + Log.Info ("{0} :: {1}", File.Basename, e.Data); + }; + Proc.Exited += HandleExited; + Proc.Start (); - Proc.BeginOutputReadLine (); + Proc.BeginErrorReadLine (); Proc.BeginOutputReadLine (); IsRunning = true; + } + + void HandleExited (object o, EventArgs args) + { + Log.Info ("{0} has exited (Code {1}).", File.Basename, Proc.ExitCode); + Proc.Exited -= HandleExited; + Proc.Dispose (); + Proc = null; + IsRunning = false; + } + + void Stop () + { + if (Proc == null) + return; - // check if the process is alive every 10 seconds. I can't figure out a better way to do this... - if (alive_timer > 0) - GLib.Source.Remove (alive_timer); - alive_timer = GLib.Timeout.Add (1000*10, delegate { - if (!FileFactory.NewForPath ("/proc").GetChild (Proc.Id.ToString ()).Exists) { - IsRunning = false; - return false; + Log.Info ("Stopping {0}", File.Basename); + + DockServices.System.RunOnThread (delegate { + // we check again because there is a bit of a race condition + if (Proc == null) + return; + + if (!Proc.HasExited) { + Proc.CancelErrorRead (); + Proc.CancelOutputRead (); + + Proc.Exited -= HandleExited; + Proc.CloseMainWindow (); + Proc.WaitForExit (500); + if (!Proc.HasExited) { + Proc.Kill (); + Proc.WaitForExit (200); + } + Log.Info ("{0} has exited (Code {1}).", File.Basename, Proc.ExitCode); } - return true; + Proc.Dispose (); + Proc = null; + + IsRunning = false; }); } - void Stop () + public void Dispose () { - if (alive_timer > 0) - GLib.Source.Remove (alive_timer); - - // Use the kill program to send off a sigterm instead of a sigkill - if (Proc != null) - System.Diagnostics.Process.Start ("kill", Proc.Id.ToString ()); - - Log.Info ("Stopping {0}", File.Basename); - IsRunning = false; + Stop (); } } } diff -Nru docky-2.0.2/Docky.Services/Docky.Services/HelperService.cs docky-2.0.4/Docky.Services/Docky.Services/HelperService.cs --- docky-2.0.2/Docky.Services/Docky.Services/HelperService.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Services/Docky.Services/HelperService.cs 2010-05-25 13:12:33.844863402 +0200 @@ -53,6 +53,7 @@ }.Where (dir => dir.Exists).Distinct (new FileEqualityComparer ()); public event EventHandler HelperStatusChanged; + public event EventHandler HelperInstalled; public event EventHandler HelperUninstalled; public bool ShowOutput { @@ -66,12 +67,12 @@ } } - IPreferences prefs; + static IPreferences prefs = DockServices.Preferences.Get (); + public List Helpers { get; private set; } public HelperService () { - prefs = DockServices.Preferences.Get (); Helpers = new List (); // set up the file monitors to watch our script directories @@ -91,6 +92,7 @@ void UpdateHelpers () { + List old_helpers = Helpers.ToList (); Helpers = Helpers.Where (h => h.File.Exists).ToList (); Helpers = HelperDirs @@ -99,12 +101,37 @@ .Select (hf => LookupHelper (hf)) .Distinct (new HelperComparer ()) .ToList (); + + if (old_helpers.Count > 0) { + List removed_helpers = old_helpers.Where (h => !Helpers.Contains (h)).ToList (); + if (removed_helpers.Count > 0) { + foreach (Helper h in removed_helpers) { + Log.Info ("Helper was removed: {0}", h.File.Path); + h.HelperStatusChanged -= OnHelperStatusChanged; + h.Dispose (); + } + OnHelperDeleted (); + } + + List added_helpers = Helpers.Where (h => !old_helpers.Contains (h)).ToList (); + if (added_helpers.Count > 0) { + foreach (Helper h in added_helpers) + Log.Info ("New helper found: {0}", h.File.Path); + OnHelperAdded (); + } + } } void OnHelperStatusChanged (object o, HelperStatusChangedEventArgs args) { if (HelperStatusChanged != null) - HelperStatusChanged (this, args); + HelperStatusChanged (o, args); + } + + void OnHelperAdded () + { + if (HelperInstalled != null) + HelperInstalled (this, EventArgs.Empty); } void OnHelperDeleted () @@ -151,9 +178,7 @@ } try { - List currentHelpers = Helpers.ToList (); UpdateHelpers (); - installedHelper = Helpers.Except (currentHelpers).First (); return true; } catch (Exception e) { Log.Error ("Error trying to install helper '{0}': {1}", file.Path, e.Message); @@ -176,7 +201,6 @@ helper.Data.IconFile.Delete (); } UpdateHelpers (); - OnHelperDeleted (); return true; } catch (Exception e) { Log.Error ("Error trying to uninstall helper '{0}': {1}", helper.File.Path, e.Message); @@ -185,5 +209,13 @@ return false; } + + public void Dispose () + { + foreach (Helper h in Helpers) { + h.HelperStatusChanged -= OnHelperStatusChanged; + h.Dispose (); + } + } } } diff -Nru docky-2.0.2/Docky.Services/Docky.Services/Log.cs docky-2.0.4/Docky.Services/Docky.Services/Log.cs --- docky-2.0.2/Docky.Services/Docky.Services/Log.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Services/Docky.Services/Log.cs 2010-05-28 16:54:56.316377343 +0200 @@ -21,7 +21,6 @@ namespace Docky.Services { - public enum LogLevel { Debug, Info, @@ -33,7 +32,6 @@ public class Log : Logging.LogBase { - public static void Debug (string msg, params object [] args) { Write (LogLevel.Debug, msg, args); diff -Nru docky-2.0.2/Docky.Services/Docky.Services/Logging/LogBase.cs docky-2.0.4/Docky.Services/Docky.Services/Logging/LogBase.cs --- docky-2.0.2/Docky.Services/Docky.Services/Logging/LogBase.cs 2010-04-11 08:04:53.607856204 +0200 +++ docky-2.0.4/Docky.Services/Docky.Services/Logging/LogBase.cs 2010-05-28 16:54:56.316377343 +0200 @@ -1,5 +1,5 @@ // -// Copyright (C) 2009 Chris Szikszoy +// Copyright (C) 2009 Chris Szikszoy, Robert Dyer // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,7 +25,6 @@ namespace Docky.Services.Logging { - public abstract class LogBase { class LogCall @@ -95,7 +94,8 @@ { if (level < DisplayLevel) return; - msg = string.Format (msg, args); + if (args.Length > 0) + msg = string.Format (msg, args); if (Writing) { // In the process of logging, another log call has been made. // We need to avoid the infinite regress this may cause. @@ -129,7 +129,10 @@ if (string.IsNullOrEmpty (sender)) title = "Docky"; - return NotificationService.Notify (title, string.Format (msg, args), icon); + if (args.Length > 0) + msg = string.Format (msg, args); + + return NotificationService.Notify (title, msg, icon); } } } diff -Nru docky-2.0.2/Docky.Services/Docky.Services/Preferences.cs docky-2.0.4/Docky.Services/Docky.Services/Preferences.cs --- docky-2.0.2/Docky.Services/Docky.Services/Preferences.cs 2010-04-12 15:03:31.793612502 +0200 +++ docky-2.0.4/Docky.Services/Docky.Services/Preferences.cs 2010-05-03 08:14:50.435828086 +0200 @@ -23,6 +23,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using GConf; using Gnome.Keyring; @@ -45,12 +46,12 @@ try { result = client.Get (AbsolutePathForKey (key, GConfPrefix)); } catch (GConf.NoSuchKeyException) { - Log.Debug ("Key {0} does not exist, creating.", key); + Log>.Debug ("Key {0} does not exist, creating.", key); Set (key, def); return def; } catch (Exception e) { - Log.Error ("Failed to get gconf value for {0} : '{1}'", key, e.Message); - Log.Info (e.StackTrace); + Log>.Error ("Failed to get gconf value for {0} : '{1}'", key, e.Message); + Log>.Info (e.StackTrace); return def; } @@ -66,8 +67,8 @@ try { client.Set (AbsolutePathForKey (key, GConfPrefix), val); } catch (Exception e) { - Log.Error ("Encountered error setting GConf key {0}: '{1}'", key, e.Message); - Log.Info (e.StackTrace); + Log>.Error ("Encountered error setting GConf key {0}: '{1}'", key, e.Message); + Log>.Info (e.StackTrace); success = false; } return success; @@ -90,8 +91,8 @@ try { client.AddNotify (path, handler); } catch (Exception e) { - Log.Error ("Error removing notification handler, {0}", e.Message); - Log.Debug (e.StackTrace); + Log>.Error ("Error removing notification handler, {0}", e.Message); + Log>.Debug (e.StackTrace); } } @@ -100,73 +101,92 @@ try { client.RemoveNotify (path, handler); } catch (Exception e) { - Log.Error ("Error removing notification handler, {0}", e.Message); - Log.Debug (e.StackTrace); + Log>.Error ("Error removing notification handler, {0}", e.Message); + Log>.Debug (e.StackTrace); } } #endregion #region IPreferences - secure, based on Gnome Keyring - object KeyringLock = new Object (); + + AutoResetEvent autoEvent = new AutoResetEvent(false); readonly string ErrorSavingMessage = "Error saving {0} : '{0}'"; readonly string KeyNotFoundMessage = "Key \"{0}\" not found in keyring"; readonly string KeyringUnavailableMessage = "gnome-keyring-daemon could not be reached!"; - const string DefaultRootPath = "docky"; + readonly string GnomeKeyringPrefix = "docky-2/" + typeof (TOwner).FullName.Replace (".", "/"); public bool SetSecure (string key, T val) { - lock (KeyringLock) { - if (typeof (T) != typeof (string)) - throw new NotImplementedException ("Unimplemented for non string values"); - - if (!Ring.Available) { - Log.Error (KeyringUnavailableMessage); - return false; - } - - Hashtable keyData = new Hashtable (); - keyData [AbsolutePathForKey (key, DefaultRootPath)] = key; - - try { - Ring.CreateItem (Ring.GetDefaultKeyring (), ItemType.GenericSecret, AbsolutePathForKey (key, DefaultRootPath), keyData, val.ToString (), true); - } catch (KeyringException e) { - Log.Error (ErrorSavingMessage, key, e.Message); - Log.Info (e.StackTrace); - return false; - } + if (typeof (T) != typeof (string)) + throw new NotImplementedException ("Unimplemented for non string values"); + + bool success = false; + + lock (autoEvent) { + DockServices.System.RunOnMainThread (() => { + try { + if (!Ring.Available) { + Log>.Error (KeyringUnavailableMessage); + return; + } + + Hashtable keyData = new Hashtable (); + keyData [AbsolutePathForKey (key, GnomeKeyringPrefix)] = key; + + Ring.CreateItem (Ring.GetDefaultKeyring (), ItemType.GenericSecret, AbsolutePathForKey (key, GnomeKeyringPrefix), keyData, val.ToString (), true); + success = true; + } catch (KeyringException e) { + Log>.Error (ErrorSavingMessage, key, e.Message); + Log>.Info (e.StackTrace); + } finally { + autoEvent.Set (); + } + }); - return true; + autoEvent.WaitOne (1000); } + + return success; } public T GetSecure (string key, T def) { - lock (KeyringLock) { - if (!Ring.Available) { - Log.Error (KeyringUnavailableMessage); - return def; - } - - Hashtable keyData = new Hashtable (); - keyData [AbsolutePathForKey (key, DefaultRootPath)] = key; - - try { - foreach (ItemData item in Ring.Find (ItemType.GenericSecret, keyData)) { - if (!item.Attributes.ContainsKey (AbsolutePathForKey (key, DefaultRootPath))) continue; - - string secureValue = item.Secret; - return (T) Convert.ChangeType (secureValue, typeof (T)); + T val = def; + + lock (autoEvent) { + DockServices.System.RunOnMainThread (() => { + try { + if (!Ring.Available) { + Log>.Error (KeyringUnavailableMessage); + return; + } + + Hashtable keyData = new Hashtable (); + keyData [AbsolutePathForKey (key, GnomeKeyringPrefix)] = key; + + foreach (ItemData item in Ring.Find (ItemType.GenericSecret, keyData)) { + if (!item.Attributes.ContainsKey (AbsolutePathForKey (key, GnomeKeyringPrefix))) continue; + + val = (T) Convert.ChangeType (item.Secret, typeof (T)); + return; + } + } catch (KeyringException e) { + Log>.Error (KeyNotFoundMessage, AbsolutePathForKey (key, GnomeKeyringPrefix), e.Message); + Log>.Info (e.StackTrace); + } finally { + autoEvent.Set (); } - } catch (KeyringException) { - Log.Error (KeyNotFoundMessage, AbsolutePathForKey (key, DefaultRootPath)); - } + }); - return def; + autoEvent.WaitOne (1000); } + + return val; } + #endregion } } diff -Nru docky-2.0.2/Docky.Services/Docky.Services/SystemService.cs docky-2.0.4/Docky.Services/Docky.Services/SystemService.cs --- docky-2.0.2/Docky.Services/Docky.Services/SystemService.cs 2010-04-12 15:03:31.793612502 +0200 +++ docky-2.0.4/Docky.Services/Docky.Services/SystemService.cs 2010-05-25 13:12:03.948613925 +0200 @@ -34,6 +34,8 @@ { public class SystemService { + public static System.Threading.Thread MainThread { get; set; } + internal SystemService () { InitializeBattery (); @@ -51,6 +53,7 @@ const string PROXY = "/system/http_proxy"; const string PROXY_USE_PROXY = PROXY + "/" + "use_http_proxy"; + const string PROXY_USE_AUTH = PROXY + "/" + "use_authentication"; const string PROXY_HOST = PROXY + "/" + "host"; const string PROXY_PORT = PROXY + "/" + "port"; const string PROXY_USER = PROXY + "/" + "authentication_user"; @@ -75,7 +78,7 @@ GConf.AddNotify (PROXY, ProxySettingsChanged); Proxy = GetWebProxy (); - } + } public event EventHandler ConnectionStatusChanged; @@ -161,8 +164,9 @@ proxy.BypassArrayList.Add (string.Format ("http://{0}", host)); } } - proxy.Credentials = new NetworkCredential (GConf.Get (PROXY_USER, ""), - GConf.Get ( PROXY_PASSWORD, "")); + if (GConf.Get (PROXY_USE_AUTH, false)) + proxy.Credentials = new NetworkCredential (GConf.Get (PROXY_USER, ""), + GConf.Get (PROXY_PASSWORD, "")); } catch (Exception e) { Log.Error ("Error creating web proxy, {0}", e.Message); Log.Debug (e.StackTrace); @@ -295,7 +299,7 @@ public void Open (IEnumerable uris) { - uris.ToList ().ForEach (uri => Open (uri)); + uris.ToList ().ForEach (uri => Open (uri)); } public void Open (GLib.File file) @@ -319,7 +323,7 @@ // check if it's a local file or on VolumeMonitor's mount list. // if it is, skip it. if (!string.IsNullOrEmpty (f.Path)) { - if (f.IsNative ||VolumeMonitor.Default.Mounts.Any (m => f.Path.Contains (m.Root.Path))) { + if (f.IsNative || VolumeMonitor.Default.Mounts.Any (m => f.Path.Contains (m.Root.Path))) { noMountNeeded.Add (f); continue; } @@ -347,8 +351,12 @@ { // if we weren't given an app info, query the file for the default handler if (app == null && files.Any ()) - app = files.First ().QueryDefaultHandler (null); - + try { + app = files.First ().QueryDefaultHandler (null); + } catch { + // file probably doesnt exist + } + GLib.List launchList; if (app != null) { @@ -403,8 +411,6 @@ } Log.Error ("Error opening files. The application doesn't support files/URIs or wasn't found."); - // fall back on xdg-open - Open (files.Select (f => f.StringUri ())); } public void Execute (string executable) @@ -429,7 +435,7 @@ proc.Dispose (); } } catch { - // FIXME + Log.Error ("Error executing '" + executable + "'"); } } @@ -466,14 +472,17 @@ public void RunOnMainThread (Action action) { - Gtk.Application.Invoke ((sender, arg) => { - try { - action (); - } catch (Exception e) { - Log.Error ("Error in RunOnMainThread: {0}", e.Message); - Log.Debug (e.StackTrace); - } - }); + if (System.Threading.Thread.CurrentThread.Equals (MainThread)) + action (); + else + Gtk.Application.Invoke ((sender, arg) => { + try { + action (); + } catch (Exception e) { + Log.Error ("Error in RunOnMainThread: {0}", e.Message); + Log.Debug (e.StackTrace); + } + }); } public void RunOnMainThread (Action action, int delay) diff -Nru docky-2.0.2/Docky.Widgets/Docky.Widgets/AbstractTileObject.cs docky-2.0.4/Docky.Widgets/Docky.Widgets/AbstractTileObject.cs --- docky-2.0.2/Docky.Widgets/Docky.Widgets/AbstractTileObject.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Widgets/Docky.Widgets/AbstractTileObject.cs 2010-05-03 07:58:13.336304374 +0200 @@ -23,7 +23,7 @@ namespace Docky.Widgets { - public abstract class AbstractTileObject + public abstract class AbstractTileObject : IDisposable { /// /// Triggered when the icon for this tile is updated @@ -289,5 +289,20 @@ OnButtonsUpdated (); } } + + #region IDisposable implementation + public virtual void Dispose () + { + if (force_pbuf != null) + force_pbuf.Dispose (); + force_pbuf = null; + + ExtraButtons.ForEach (button => { + button.Dispose (); + button.Destroy (); + }); + ExtraButtons.Clear (); + } + #endregion } } diff -Nru docky-2.0.2/Docky.Widgets/Docky.Widgets/AnimatedBox.cs docky-2.0.4/Docky.Widgets/Docky.Widgets/AnimatedBox.cs --- docky-2.0.2/Docky.Widgets/Docky.Widgets/AnimatedBox.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Widgets/Docky.Widgets/AnimatedBox.cs 2010-05-03 07:58:13.347077960 +0200 @@ -540,6 +540,13 @@ } #endregion - + + public override void Dispose () + { + stage.ActorStep -= OnActorStep; + border_stage.Iteration -= OnBorderIteration; + + base.Dispose (); + } } } \ Kein Zeilenumbruch am Dateiende. diff -Nru docky-2.0.2/Docky.Widgets/Docky.Widgets/ListOnlyTileView.cs docky-2.0.4/Docky.Widgets/Docky.Widgets/ListOnlyTileView.cs --- docky-2.0.2/Docky.Widgets/Docky.Widgets/ListOnlyTileView.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Widgets/Docky.Widgets/ListOnlyTileView.cs 2010-05-07 12:04:03.668231220 +0200 @@ -36,11 +36,11 @@ public override void OnTileActiveChanged (object o, EventArgs args) { + base.OnTileActiveChanged (o, args); + Tile t = o as Tile; RemoveTile (t.OwnedObject); - - base.OnTileActiveChanged (o, args); } } } diff -Nru docky-2.0.2/Docky.Widgets/Docky.Widgets/Tile.cs docky-2.0.4/Docky.Widgets/Docky.Widgets/Tile.cs --- docky-2.0.2/Docky.Widgets/Docky.Widgets/Tile.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Widgets/Docky.Widgets/Tile.cs 2010-05-03 07:58:13.377077445 +0200 @@ -1,3 +1,19 @@ +// +// Copyright (C) 2010 Rico Tzschichholz +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// // // Tile.cs // @@ -61,17 +77,9 @@ { OwnedObject = obj; - OwnedObject.IconUpdated += delegate { - SetImage (); - }; - - OwnedObject.TextUpdated += delegate { - SetText (); - }; - - OwnedObject.ButtonsUpdated += delegate { - UpdateButtons (); - }; + OwnedObject.IconUpdated += HandleOwnedObjectIconUpdated; + OwnedObject.TextUpdated += HandleOwnedObjectTextUpdated; + OwnedObject.ButtonsUpdated += HandleOwnedObjectButtonsUpdated; IconSize = iconSize; @@ -247,5 +255,31 @@ UpdateState (); QueueResize (); } + + void HandleOwnedObjectButtonsUpdated (object sender, EventArgs e) + { + UpdateButtons (); + } + + void HandleOwnedObjectTextUpdated (object sender, EventArgs e) + { + SetText (); + } + + void HandleOwnedObjectIconUpdated (object sender, EventArgs e) + { + SetImage (); + } + + public override void Dispose () + { + OwnedObject.IconUpdated -= HandleOwnedObjectIconUpdated; + OwnedObject.TextUpdated -= HandleOwnedObjectTextUpdated; + OwnedObject.ButtonsUpdated -= HandleOwnedObjectButtonsUpdated; + + OwnedObject = null; + + base.Dispose (); + } } } \ Kein Zeilenumbruch am Dateiende. diff -Nru docky-2.0.2/Docky.Widgets/Docky.Widgets/TileView.cs docky-2.0.4/Docky.Widgets/Docky.Widgets/TileView.cs --- docky-2.0.2/Docky.Widgets/Docky.Widgets/TileView.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Widgets/Docky.Widgets/TileView.cs 2010-05-07 12:28:35.688230412 +0200 @@ -1,3 +1,19 @@ +// +// Copyright (C) 2010 Rico Tzschichholz +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// // // AddinView.cs // @@ -68,12 +84,33 @@ public void Clear () { + tiles.ForEach (tile => { + tile.Hide (); + tile.ActiveChanged -= OnTileActiveChanged; + tile.SizeAllocated -= OnTileSizeAllocated; + tile.Owner = null; + }); tiles.Clear (); + foreach (Widget child in box.Children) { box.Remove (child); + child.Dispose (); + child.Destroy (); } } + public virtual void AppendTile (AbstractTileObject tileObject) + { + Tile tile = new Tile (tileObject, IconSize); + tile.Owner = this; + tile.ActiveChanged += OnTileActiveChanged; + tile.SizeAllocated += OnTileSizeAllocated; + tile.Show (); + tiles.Add (tile); + + box.PackStart (tile, false, false, 0); + } + public virtual void RemoveTile (AbstractTileObject tileObject) { Tile tile = tiles.First (t => t.OwnedObject == tileObject); @@ -83,8 +120,16 @@ if (selected_index == tiles.IndexOf (tile)) ClearSelection (); + + tile.Hide (); + tile.ActiveChanged -= OnTileActiveChanged; + tile.SizeAllocated -= OnTileSizeAllocated; + tile.Owner = null; + tiles.Remove (tile); box.Remove (tile); + tile.Dispose (); + tile.Destroy (); } public virtual void ClearSelection () @@ -96,18 +141,6 @@ selected_index = -1; } - public virtual void AppendTile (AbstractTileObject tileObject) - { - Tile tile = new Tile (tileObject, IconSize); - tile.Owner = this; - tile.ActiveChanged += OnTileActiveChanged; - tile.SizeAllocated += OnTileSizeAllocated; - tile.Show (); - tiles.Add (tile); - - box.PackStart (tile, false, false, 0); - } - private bool changing_styles = false; protected override void OnStyleSet (Style previous_style) @@ -228,5 +261,17 @@ QueueResize (); } + + public override void Dispose () + { + Clear (); + + if (box != null) { + box.Dispose (); + box.Destroy (); + } + + base.Dispose (); + } } } diff -Nru docky-2.0.2/Docky.Windowing/Windowing/DesktopItem.cs docky-2.0.4/Docky.Windowing/Windowing/DesktopItem.cs --- docky-2.0.2/Docky.Windowing/Windowing/DesktopItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Docky.Windowing/Windowing/DesktopItem.cs 2010-05-03 10:39:47.785827961 +0200 @@ -189,7 +189,12 @@ public void Launch (IEnumerable uris) { - DockServices.System.Open (GLib.DesktopAppInfo.NewFromFilename (Location), uris.Select (uri => GLib.FileFactory.NewForUri (uri))); + if (!File.Exists (Location)) + return; + + using (GLib.DesktopAppInfo appinfo = GLib.DesktopAppInfo.NewFromFilename (Location)) { + DockServices.System.Open (appinfo, uris.Select (uri => GLib.FileFactory.NewForUri (uri))); + } } #region IDisposable implementation diff -Nru docky-2.0.2/Docky.Windowing/Windowing/WindowMatcher.cs docky-2.0.4/Docky.Windowing/Windowing/WindowMatcher.cs --- docky-2.0.2/Docky.Windowing/Windowing/WindowMatcher.cs 2010-04-11 08:08:42.875356014 +0200 +++ docky-2.0.4/Docky.Windowing/Windowing/WindowMatcher.cs 2010-05-25 16:54:56.114876079 +0200 @@ -317,7 +317,7 @@ return win.EndsWith (".desktop"); } - bool WindowIsOpenOffice (Wnck.Window window) + public bool WindowIsOpenOffice (Wnck.Window window) { return window.ClassGroup != null && window.ClassGroup.Name.ToLower ().StartsWith ("openoffice"); } @@ -603,7 +603,7 @@ string vexec = null; if (exec.Contains (' ') && - (exec.StartsWith ("ooffice") || exec.StartsWith ("openoffice.org3") || exec.StartsWith ("soffice.bin"))) { + (exec.StartsWith ("ooffice") || exec.StartsWith ("openoffice") || exec.StartsWith ("soffice"))) { vexec = "ooffice" + exec.Split (' ') [1]; // for wine apps } else if ((exec.StartsWith ("env WINEPREFIX=") && exec.Contains (" wine ")) || @@ -629,11 +629,17 @@ using (GLib.DataInputStream stream = new GLib.DataInputStream (launcher.Read (null))) { ulong len; string line; - while ((line = stream.ReadLine (out len, null)) != null) { - if (line.StartsWith ("exec")) { - execLine = line; - break; + try { + while ((line = stream.ReadLine (out len, null)) != null) { + if (line.StartsWith ("exec")) { + execLine = line; + break; + } } + } catch (Exception e) { + Log.Error (e.Message); + Log.Error (e.StackTrace); + continue; } } diff -Nru docky-2.0.2/Makefile.am docky-2.0.4/Makefile.am --- docky-2.0.2/Makefile.am 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/Makefile.am 2010-05-03 10:46:11.585827734 +0200 @@ -1,4 +1,7 @@ -EXTRA_DIST = config.rpath COPYRIGHT +EXTRA_DIST = \ + config.rpath \ + COPYRIGHT \ + NEWS ACLOCAL_AMFLAGS = -I m4 -I m4/shamrock diff -Nru docky-2.0.2/Makefile.in docky-2.0.4/Makefile.in --- docky-2.0.2/Makefile.in 2010-04-12 15:07:30.357361433 +0200 +++ docky-2.0.4/Makefile.in 2010-05-31 08:00:13.035620638 +0200 @@ -45,7 +45,7 @@ $(top_srcdir)/StandardPlugins/RecentDocuments/Resources/RecentDocuments.addin.xml.in \ $(top_srcdir)/StandardPlugins/Trash/Resources/Trash.addin.xml.in \ $(top_srcdir)/StandardPlugins/Weather/Resources/Weather.addin.xml.in \ - $(top_srcdir)/configure AUTHORS COPYING config.rpath \ + $(top_srcdir)/configure AUTHORS COPYING NEWS config.rpath \ install-sh missing py-compile ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/shamrock/expansions.m4 \ @@ -307,7 +307,11 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -EXTRA_DIST = config.rpath COPYRIGHT +EXTRA_DIST = \ + config.rpath \ + COPYRIGHT \ + NEWS + ACLOCAL_AMFLAGS = -I m4 -I m4/shamrock SUBDIRS = \ . \ diff -Nru docky-2.0.2/NEWS docky-2.0.4/NEWS --- docky-2.0.2/NEWS 1970-01-01 01:00:00.000000000 +0100 +++ docky-2.0.4/NEWS 2010-05-31 07:54:32.944372006 +0200 @@ -0,0 +1,153 @@ +Docky: The finest dock no money can buy! + +2.0.4 "Do you think you're better off alone?" (2010-05-31) +=============================================================================== + * Bug-fix and Maintenance Release + * update translations + + CORE: + * fix positioning of menus/hovers on multimon setups (LP: #544047) + * make settings dialog smaller so it fits on netbook screens (LP: #581458) + * FileApplicationProvider.PinToDock misses a handle-removal + This caused a duplicated item when restarting a just pinned application and + leads to a crash when trying to pin the new item (LP: #585136) + * update transient items when moving the active window (LP: #581077) + * fix crash when a file is on the dock where this file no longer exists + (LP: #581074) + * fix drag'n'drop-hover-strings (LP: #556041) + * add call to GLib.Thread.Init (LP: #586969) + * Window-Matching + - better OpenOffice handling (LP: #486887) (LP: #580275) + (LP: #504486) (LP: #580275) + * Helper + - fix a crash regarding helpers terminating + - fix killing helpers from prefs menu + - fix potential crash when disabling helpers + - cleanup the helpers, fix a few possible leaks in them + + DOCKLETS: + * Clock: fix problems with the small clock rendering + * GMail: + - fix compose mail url in GMail docklet for Google app domains (LP: #582212) + - fix crash when removing a gmail label (LP: #576596) + - refresh be set up to 1 day (1440 mins) long (LP: #580441) + - missing string internationalization in GMail + * RecentDocuments: better locking to avoid crashes when clearing + recent documents (LP: #580723) + * Weather: make sure weather doesn't reload when prefs open (LP: #580314) + * Bookmarks: stop spurious errors when dragging files over + unmounted bookmarks (LP: #580361) + * NPR: fix failing to load after network comes back up (LP: #523155) + + HELPER: + * make banshee and rhythmbox helper a bit smarter looking + for art-cover-files (LP: #578254) + * fix class-names in the deluge helper + * change open terminal here helper to use the gnome default terminal, + with a fallback to gnome-terminal if the default is not set + * fix issues with newer zeitgeist version (LP: #570286) + + +2.0.3.1 "You should have heard from us by now" (2010-05-03) +=============================================================================== + * Bug-fix and Maintenance Release + * update translations + + CORE: + * fix gnome-keyring related crash in Lucid caused by GMail docklet (LP: #555562) + * catch exception for read-failure of cxoffice launcher (LP: #573294) + * check if authentication is used before using network proxy + * make sure to update screen regions when showing menus + * make transparent themed docks still glow in configuration mode (LP: #572416) + * Memory Leaks + - some unlinked handlers and pixbufs (DockItemMenu, WindowDockItem, ...) + - proper disposal of tile-widgets in preferences dialog + - properly using DesktopAppInfo for launching application + + DOCKLETS: + * GMail: fix exception when reloading (LP: #573991) + * Clock: popup menu must always show icons (LP: #574003) + + HELPER: + * helpers crash when dbus isn't available (LP: #540688) + + +2.0.2 "Living on the screen's edge" (2010-04-12) +=============================================================================== + * Bug-fix and Maintenance Release + * update translations + * fix MonoDevelop build + * update homepage link in about dialog + + CORE: + * add automatic enabling of --nvidia flag + * respect system proxy settings (LP: #546135) + * add directions to select a dock to configure to the settings dialog + docklets tab (LP: #555153) + * fix freeze when MaxIconSize updates (LP: #495155) (LP: #506436) (LP: #518304) + (LP: #519938) (LP: #543123) + * add locking to secure preferences, possibly avoid a gnome-keyring + related crash + * fix hiding with fullscreen windows with multiple monitors (LP: #533872) + * fix right alignment of docklets when no launchers (LP: #550417) + * fix manual override of Docky icon color (LP: #549154) + * let urgent glow pulse for 10s (5 pulses) + * fix render bug with painter icons + * add UPower support for lucid + * fix helper status updating in config dialog (LP: #547115) + * Memory Leaks + - fix leak associated with GLib.FileInfo + - fix leak in NativeInterop + - fix leak in ApplicationDockItem + * WindowMatcher + - use a NoDisplay launcher if there isn't already a launcher for that + exec (LP: #558755) + - fix matching executables that end in a version number (LP: #558780) + - fix OpenOffice.org matching in more cases and clean up matching code + - add support for matching windows based on StartupWMClass launcher + attribute (LP: #518828) + this gives a workaround/solution for (LP: #484610) + - fix Wine application matching regression (LP: #552396) + - fix bug where custom launchers were not being matched (LP: #543837) + + DOCKLETS: + * adding icon fallbacks to some docklets + * Gmail: fix handling of labels with strange chars and escaping problems + * Gmail: fix checking date parse problem (LP: #554333) + * Mounter: really fix NullReferenceException (LP: #536915) + * Weather/Gmail: add proper thread shutdown + + +2.0.1 "We require somewhere new" (2010-03-16) +=============================================================================== + * Bug-fix and Maintenance Release + * update translations + + CORE: + * add timeouts to HttpWebRequests + * properly initialize config window - information-text is not shown when + there is more than one dock + * fix version output on console + * Handle InvalidOperationException thrown by AddinManger.Initalize + * properly disable plugin when it gets dragged of a dock + * set a min height on the calendar painter + + DOCKLETS: + * GMail: prevent concurrent mail checking + * Mounter: fix a crash and a possible crash (LP: #536915) + * RecentDocuments: sort list before limiting it (LP: #538027) + * Trash: nicer description + * Weather: prevent concurrent reloads + * Weather: fix painter crash (LP: #527952) + + HELPER: + * Banshee: cover folder fix for 1.5.5 (LP: #538728) + * Helper metadata are not scripts. Install them as data, rather than as + executables + + +2.0.0 "People love our huge docks" (2010-02-16) +=============================================================================== + * Initial Release + + diff -Nru docky-2.0.2/po/ast.po docky-2.0.4/po/ast.po diff -Nru docky-2.0.2/po/bg.po docky-2.0.4/po/bg.po diff -Nru docky-2.0.2/po/bn.po docky-2.0.4/po/bn.po diff -Nru docky-2.0.2/po/ca.po docky-2.0.4/po/ca.po diff -Nru docky-2.0.2/po/de.po docky-2.0.4/po/de.po diff -Nru docky-2.0.2/po/en_GB.po docky-2.0.4/po/en_GB.po diff -Nru docky-2.0.2/po/es.po docky-2.0.4/po/es.po diff -Nru docky-2.0.2/po/eu.po docky-2.0.4/po/eu.po diff -Nru docky-2.0.2/po/fi.po docky-2.0.4/po/fi.po diff -Nru docky-2.0.2/po/fr.po docky-2.0.4/po/fr.po diff -Nru docky-2.0.2/po/gl.po docky-2.0.4/po/gl.po diff -Nru docky-2.0.2/po/he.po docky-2.0.4/po/he.po diff -Nru docky-2.0.2/po/hi.po docky-2.0.4/po/hi.po diff -Nru docky-2.0.2/po/hr.po docky-2.0.4/po/hr.po diff -Nru docky-2.0.2/po/hu.po docky-2.0.4/po/hu.po diff -Nru docky-2.0.2/po/id.po docky-2.0.4/po/id.po diff -Nru docky-2.0.2/po/is.po docky-2.0.4/po/is.po diff -Nru docky-2.0.2/po/it.po docky-2.0.4/po/it.po diff -Nru docky-2.0.2/po/ja.po docky-2.0.4/po/ja.po diff -Nru docky-2.0.2/po/ko.po docky-2.0.4/po/ko.po diff -Nru docky-2.0.2/po/pl.po docky-2.0.4/po/pl.po diff -Nru docky-2.0.2/po/POTFILES.in docky-2.0.4/po/POTFILES.in --- docky-2.0.2/po/POTFILES.in 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/po/POTFILES.in 2010-05-25 19:03:05.224864352 +0200 @@ -7,6 +7,7 @@ Docky/Docky/Items/DockyItem.cs Docky/gtk-gui/Docky.ConfigurationWindow.cs Docky/gtk-gui/Docky.Interface.DockPreferences.cs +Docky.Items/Docky.Items/AbstractDockItem.cs Docky.Items/Docky.Items/ApplicationDockItem.cs Docky.Items/Docky.Items/ColoredIconDockItem.cs Docky.Items/Docky.Items/FileApplicationProvider.cs diff -Nru docky-2.0.2/po/pt_BR.po docky-2.0.4/po/pt_BR.po diff -Nru docky-2.0.2/po/ro.po docky-2.0.4/po/ro.po diff -Nru docky-2.0.2/po/ru.po docky-2.0.4/po/ru.po diff -Nru docky-2.0.2/po/sv.po docky-2.0.4/po/sv.po diff -Nru docky-2.0.2/po/tr.po docky-2.0.4/po/tr.po diff -Nru docky-2.0.2/po/uk.po docky-2.0.4/po/uk.po diff -Nru docky-2.0.2/po/zh_CN.po docky-2.0.4/po/zh_CN.po diff -Nru docky-2.0.2/scripts/banshee_control.py docky-2.0.4/scripts/banshee_control.py --- docky-2.0.2/scripts/banshee_control.py 2010-03-16 09:55:32.856565217 +0100 +++ docky-2.0.4/scripts/banshee_control.py 2010-05-25 12:45:03.184863523 +0200 @@ -60,6 +60,7 @@ self.duration_secs = 0 self.songinfo = None self.current_arturl = "" + self.current_arturl_mtime = 0 self.bus.add_signal_receiver(self.name_owner_changed_cb, dbus_interface='org.freedesktop.DBus', @@ -177,14 +178,16 @@ if self.banshee_is_playing(): arturl = self.get_album_art_path() - if not self.current_arturl == arturl: - # Add overlay to cover - if os.path.isfile(arturl): - self.current_arturl = arturl - self.iface.SetIcon(self.get_album_art_overlay_path(arturl)) - else: - self.current_arturl = "" - self.iface.ResetIcon() + # Add overlay to cover + if os.path.isfile(arturl): + if self.current_arturl == arturl and self.current_arturl_mtime == os.stat(arturl).st_mtime: + return True + self.current_arturl = arturl + self.current_arturl_mtime = os.stat(arturl).st_mtime + self.iface.SetIcon(self.get_album_art_overlay_path(arturl)) + else: + self.current_arturl = "" + self.iface.ResetIcon() else: self.current_arturl = "" self.iface.ResetIcon() diff -Nru docky-2.0.2/scripts/deluge_badge.py docky-2.0.4/scripts/deluge_badge.py --- docky-2.0.2/scripts/deluge_badge.py 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/scripts/deluge_badge.py 2010-05-25 13:25:25.238582577 +0200 @@ -55,7 +55,7 @@ return str(scaled_bytes) + unit -class DockyLifereaItem(DockyItem): +class DockyDelugeItem(DockyItem): def __init__(self, path): DockyItem.__init__(self, path) @@ -85,12 +85,12 @@ return False -class DockyLifereaSink(DockySink): +class DockyDelugeSink(DockySink): def item_path_found(self, pathtoitem, item): if item.GetOwnsDesktopFile() and item.GetDesktopFile().endswith ("deluge.desktop"): - self.items[pathtoitem] = DockyLifereaItem(pathtoitem) + self.items[pathtoitem] = DockyDelugeItem(pathtoitem) -dockysink = DockyLifereaSink() +dockysink = DockyDelugeSink() def cleanup (): dockysink.dispose () diff -Nru docky-2.0.2/scripts/docky/docky.py docky-2.0.4/scripts/docky/docky.py --- docky-2.0.2/scripts/docky/docky.py 2010-04-12 15:07:34.147362165 +0200 +++ docky-2.0.4/scripts/docky/docky.py 2010-05-31 08:00:18.224372004 +0200 @@ -39,11 +39,15 @@ self.bus = dbus.SessionBus() self.id_map = {} - obj = self.bus.get_object(dockybus, self.path) - self.iface = dbus.Interface(obj, itemiface) - - self.bus.add_signal_receiver(self.menu_pressed_signal, "MenuItemActivated", itemiface, dockybus, self.path) - self.bus.add_signal_receiver(self.item_confirmation_needed, "ItemConfirmationNeeded", itemiface, dockybus, self.path) + try: + obj = self.bus.get_object(dockybus, self.path) + self.iface = dbus.Interface(obj, itemiface) + + self.bus.add_signal_receiver(self.menu_pressed_signal, "MenuItemActivated", itemiface, dockybus, self.path) + self.bus.add_signal_receiver(self.item_confirmation_needed, "ItemConfirmationNeeded", itemiface, dockybus, self.path) + except dbus.DBusException, e: + print "DockyItem(): %s" % e + sys.exit(0) def menu_pressed_signal(self, menu_id): if self.id_map.has_key(menu_id): @@ -76,23 +80,23 @@ try: obj = self.bus.get_object(dockybus, dockypath) self._iface = dbus.Interface(obj, dockyiface) + + paths = self._iface.DockItemPaths() + + self.bus.add_signal_receiver(self.item_added, "ItemAdded", dockyiface, dockybus, dockypath) + self.bus.add_signal_receiver(self.item_removed, "ItemRemoved", dockyiface, dockybus, dockypath) + self.bus.add_signal_receiver(self.shut_down, "ShuttingDown", dockyiface, dockybus, dockypath) + + for pathtoitem in paths: + obj = self.bus.get_object(dockybus, pathtoitem) + item = dbus.Interface(obj, itemiface) + self.item_path_found(pathtoitem, item) + + self.bus.add_signal_receiver(self.name_owner_changed_cb, dbus_interface='org.freedesktop.DBus', signal_name='NameOwnerChanged') except dbus.DBusException, e: print "DockySink(): %s" % e sys.exit(0) - paths = self._iface.DockItemPaths() - - self.bus.add_signal_receiver(self.item_added, "ItemAdded", dockyiface, dockybus, dockypath) - self.bus.add_signal_receiver(self.item_removed, "ItemRemoved", dockyiface, dockybus, dockypath) - self.bus.add_signal_receiver(self.shut_down, "ShuttingDown", dockyiface, dockybus, dockypath) - - for pathtoitem in paths: - obj = self.bus.get_object(dockybus, pathtoitem) - item = dbus.Interface(obj, itemiface) - self.item_path_found(pathtoitem, item) - - self.bus.add_signal_receiver(self.name_owner_changed_cb, dbus_interface='org.freedesktop.DBus', signal_name='NameOwnerChanged') - def name_owner_changed_cb(self, name, old_owner, new_owner): if name == dockybus and not new_owner: print "DockyDBus %s is gone, quitting now..." % name diff -Nru docky-2.0.2/scripts/docky/docky.py.in docky-2.0.4/scripts/docky/docky.py.in --- docky-2.0.2/scripts/docky/docky.py.in 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/scripts/docky/docky.py.in 2010-05-03 08:12:24.405827668 +0200 @@ -39,11 +39,15 @@ self.bus = dbus.SessionBus() self.id_map = {} - obj = self.bus.get_object(dockybus, self.path) - self.iface = dbus.Interface(obj, itemiface) - - self.bus.add_signal_receiver(self.menu_pressed_signal, "MenuItemActivated", itemiface, dockybus, self.path) - self.bus.add_signal_receiver(self.item_confirmation_needed, "ItemConfirmationNeeded", itemiface, dockybus, self.path) + try: + obj = self.bus.get_object(dockybus, self.path) + self.iface = dbus.Interface(obj, itemiface) + + self.bus.add_signal_receiver(self.menu_pressed_signal, "MenuItemActivated", itemiface, dockybus, self.path) + self.bus.add_signal_receiver(self.item_confirmation_needed, "ItemConfirmationNeeded", itemiface, dockybus, self.path) + except dbus.DBusException, e: + print "DockyItem(): %s" % e + sys.exit(0) def menu_pressed_signal(self, menu_id): if self.id_map.has_key(menu_id): @@ -76,23 +80,23 @@ try: obj = self.bus.get_object(dockybus, dockypath) self._iface = dbus.Interface(obj, dockyiface) + + paths = self._iface.DockItemPaths() + + self.bus.add_signal_receiver(self.item_added, "ItemAdded", dockyiface, dockybus, dockypath) + self.bus.add_signal_receiver(self.item_removed, "ItemRemoved", dockyiface, dockybus, dockypath) + self.bus.add_signal_receiver(self.shut_down, "ShuttingDown", dockyiface, dockybus, dockypath) + + for pathtoitem in paths: + obj = self.bus.get_object(dockybus, pathtoitem) + item = dbus.Interface(obj, itemiface) + self.item_path_found(pathtoitem, item) + + self.bus.add_signal_receiver(self.name_owner_changed_cb, dbus_interface='org.freedesktop.DBus', signal_name='NameOwnerChanged') except dbus.DBusException, e: print "DockySink(): %s" % e sys.exit(0) - paths = self._iface.DockItemPaths() - - self.bus.add_signal_receiver(self.item_added, "ItemAdded", dockyiface, dockybus, dockypath) - self.bus.add_signal_receiver(self.item_removed, "ItemRemoved", dockyiface, dockybus, dockypath) - self.bus.add_signal_receiver(self.shut_down, "ShuttingDown", dockyiface, dockybus, dockypath) - - for pathtoitem in paths: - obj = self.bus.get_object(dockybus, pathtoitem) - item = dbus.Interface(obj, itemiface) - self.item_path_found(pathtoitem, item) - - self.bus.add_signal_receiver(self.name_owner_changed_cb, dbus_interface='org.freedesktop.DBus', signal_name='NameOwnerChanged') - def name_owner_changed_cb(self, name, old_owner, new_owner): if name == dockybus and not new_owner: print "DockyDBus %s is gone, quitting now..." % name diff -Nru docky-2.0.2/scripts/open_terminal_here.py docky-2.0.4/scripts/open_terminal_here.py --- docky-2.0.2/scripts/open_terminal_here.py 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/scripts/open_terminal_here.py 2010-05-25 13:28:12.144863762 +0200 @@ -18,6 +18,7 @@ # import atexit +import gconf import gobject import glib import sys @@ -34,6 +35,12 @@ class DockyTerminalItem(DockyItem): def __init__(self, path): DockyItem.__init__(self, path) + + client = gconf.client_get_default() + self.terminal = client.get_string("/desktop/gnome/applications/terminal/exec") + if self.terminal == None: + self.terminal = "gnome-terminal" + self.path = urllib.unquote(str(self.iface.GetUri ()[7:])) if not os.path.isdir (self.path): self.path = os.path.dirname (self.path) @@ -42,7 +49,8 @@ def menu_pressed(self, menu_id): if self.id_map[menu_id] == "Open Terminal Here": - os.system ("gnome-terminal --working-directory=\"" + self.path + "\"") + os.chdir(self.path); + os.system ('%s &' % self.terminal) def add_menu_item(self, name, icon): menu_id = self.iface.AddMenuItem(name, icon, "actions") diff -Nru docky-2.0.2/scripts/rhythmbox_control.py docky-2.0.4/scripts/rhythmbox_control.py --- docky-2.0.2/scripts/rhythmbox_control.py 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/scripts/rhythmbox_control.py 2010-05-25 12:45:03.194863413 +0200 @@ -75,6 +75,7 @@ self.songinfo = None self.cover_basename = "" self.current_arturl = "" + self.current_arturl_mtime = 0 self.bus.add_signal_receiver(self.name_owner_changed_cb, dbus_interface='org.freedesktop.DBus', @@ -187,14 +188,16 @@ if self.rhythmbox_is_playing(): arturl = self.get_album_art_path() - if not self.current_arturl == arturl: - # Add overlay to cover - if os.path.isfile(arturl): - self.current_arturl = arturl - self.iface.SetIcon(self.get_album_art_overlay_path(arturl)) - else: - self.current_arturl = "" - self.iface.ResetIcon() + # Add overlay to cover + if os.path.isfile(arturl): + if self.current_arturl == arturl and self.current_arturl_mtime == os.stat(arturl).st_mtime: + return True + self.current_arturl = arturl + self.current_arturl_mtime = os.stat(arturl).st_mtime + self.iface.SetIcon(self.get_album_art_overlay_path(arturl)) + else: + self.current_arturl = "" + self.iface.ResetIcon() else: self.current_arturl = "" self.iface.ResetIcon() @@ -211,8 +214,11 @@ #1. Look in song folder #TODO need to replace some things, this is very weird coverdir = os.path.dirname(filename) - covernames = ["cover.jpg", "cover.png", "album.jpg", "album.png", "albumart.jpg", - "albumart.png", ".folder.jpg", ".folder.png", "folder.jpg", "folder.png"] + covernames = ["cover.jpg", "cover.png", "Cover.jpg", "Cover.png", + "album.jpg", "album.png", "Album.jpg", "Album.png", + "albumart.jpg", "albumart.png", "Albumart.jpg", "Albumart.png", + ".folder.jpg", ".folder.png", ".Folder.jpg", ".Folder.png", + "folder.jpg", "folder.png", "Folder.jpg", "Folder.png"] for covername in covernames: arturl = os.path.join(coverdir, covername) if os.path.isfile(arturl): diff -Nru docky-2.0.2/scripts/zeitgeist_docky.py docky-2.0.4/scripts/zeitgeist_docky.py --- docky-2.0.2/scripts/zeitgeist_docky.py 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/scripts/zeitgeist_docky.py 2010-05-25 14:22:51.826113858 +0200 @@ -1,7 +1,7 @@ #!/usr/bin/env python # -# Copyright (C) 2009 Jason Smith, Seif Lofty +# Copyright (C) 2009 Jason Smith, Seif Lotfy # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -40,9 +40,9 @@ try: CLIENT = ZeitgeistClient() version = [int(x) for x in CLIENT.get_version()] - MIN_VERSION = [0, 3, 1, 0] + MIN_VERSION = [0, 3, 2, 0] if version < MIN_VERSION: - print "PLEASE USE ZEITGEIST 0.3.1 or above" + print "PLEASE USE ZEITGEIST 0.3.2 or above" exit() @@ -53,6 +53,7 @@ class MostUsedProvider(): def __init__(self): self._zg = CLIENT + self.results = [] def get_path_most_used(self, path, handler, is_directoy=True): today = time.time() * 1000 @@ -66,31 +67,42 @@ def _handle_get_events(events): uris = [] - counter = 0 + uris_counter = {} for event in events: - if counter < 5: - for subject in event.subjects: - if counter < 5 and exists(subject.uri): - uris.append(subject) - counter+=1 - elif counter >= 5: - break - else: - pass - #print "skipping", subject.uri - else: - break - handler(uris) + for subject in event.subjects: + if exists(subject.uri): + if not subject.uri in uris: + uris.append(subject.uri) + uris_counter[subject.uri] = 0 + uris_counter[subject.uri] += 1 + + counter = [] + for k, v in uris_counter.iteritems(): + counter.append((v, k)) + counter.sort(reverse = True) + + recent =[] + temp = [i[1] for i in counter] + for uri in uris: + if not uri in temp[0:5]: + recent.append(uri) + results = [] + results.append(recent[0:5]) + + results.append(counter[0:5]) + handler(results) event = Event() if is_directoy: subject = Subject() subject.set_origin(path) event.set_subjects([subject]) - self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 4) + self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 0) else: + path = "application://" + path.split("/")[-1] event.set_actor(path) - self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 4) + self._zg.find_events_for_templates([event],_handle_get_events, [delta, today], StorageState.Any, 0, 0) + class DockyZGItem(DockyItem): def __init__(self, path): @@ -108,10 +120,17 @@ return self.mostusedprovider.get_path_most_used (self.uri, self._handle_get_most_used, self.iface.GetOwnsUri ()) - def _handle_get_most_used(self, uris): - for subject in uris: - menu_id = self.iface.AddFileMenuItem(subject.uri,"Most Used Items") - self.id_map[menu_id] = subject.uri + def _handle_get_most_used(self, results): + uris = results[0] + if len(uris) > 0: + for subject in uris: + menu_id = self.iface.AddFileMenuItem(subject ,"Other Recently Used Items") + self.id_map[menu_id] = subject + uris = results[1] + if len(uris) > 0: + for subject in uris: + menu_id = self.iface.AddFileMenuItem(subject[1], "Most Used Items") + self.id_map[menu_id] = subject class DockyZGSink(DockySink): def item_path_found(self, pathtoitem, item): diff -Nru docky-2.0.2/StandardPlugins/Clock/src/ClockDockItem.cs docky-2.0.4/StandardPlugins/Clock/src/ClockDockItem.cs --- docky-2.0.2/StandardPlugins/Clock/src/ClockDockItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/StandardPlugins/Clock/src/ClockDockItem.cs 2010-05-25 13:23:27.977364250 +0200 @@ -193,24 +193,26 @@ else HoverText = DateTime.Now.ToString ("ddd, MMM dd h:mm tt"); - int size = Math.Min (surface.Width, surface.Height); - - if (ShowDigital && Square) - MakeSquareDigitalIcon (surface.Context, size); - else if (ShowDigital && !Square) - MakeRectangularDigitalIcon (surface.Context, size); - else - MakeAnalogIcon (surface.Context, size); + if (ShowDigital) { + if (Square) + MakeSquareDigitalIcon (surface); + else + MakeRectangularDigitalIcon (surface); + } else { + MakeAnalogIcon (surface.Context, Math.Min (surface.Width, surface.Height)); + } } - void MakeSquareDigitalIcon (Context cr, int size) + void MakeSquareDigitalIcon (DockySurface surface) { + Context cr = surface.Context; + // useful sizes - int timeSize = size / 4; - int dateSize = size / 5; - int ampmSize = size / 5; + int timeSize = surface.Height / 4; + int dateSize = surface.Height / 5; + int ampmSize = surface.Height / 5; int spacing = timeSize / 2; - int center = size / 2; + int center = surface.Height / 2; // shared by all text Pango.Layout layout = DockServices.Drawing.ThemedPangoLayout (); @@ -218,7 +220,7 @@ layout.FontDescription = new Gtk.Style().FontDescription; layout.FontDescription.Weight = Pango.Weight.Bold; layout.Ellipsize = Pango.EllipsizeMode.None; - layout.Width = Pango.Units.FromPixels (size); + layout.Width = Pango.Units.FromPixels (surface.Width); // draw the time, outlined @@ -233,7 +235,7 @@ layout.GetPixelExtents (out inkRect, out logicalRect); int timeYOffset = ShowMilitary ? timeSize : timeSize / 2; - int timeXOffset = (size - inkRect.Width) / 2; + int timeXOffset = (surface.Width - inkRect.Width) / 2; if (ShowDate) cr.MoveTo (timeXOffset, timeYOffset); else @@ -252,7 +254,7 @@ layout.SetText (DateTime.Now.ToString ("MMM dd")); layout.GetPixelExtents (out inkRect, out logicalRect); - cr.MoveTo ((size - inkRect.Width) / 2, size - spacing - dateSize); + cr.MoveTo ((surface.Width - inkRect.Width) / 2, surface.Height - spacing - dateSize); Pango.CairoHelper.LayoutPath (cr, layout); cr.LineWidth = 2.5; @@ -265,7 +267,7 @@ if (!ShowMilitary) { layout.FontDescription.AbsoluteSize = Pango.Units.FromPixels (ampmSize); - int yOffset = ShowDate ? center - spacing : size - spacing - ampmSize; + int yOffset = ShowDate ? center - spacing : surface.Height - spacing - ampmSize; // draw AM indicator layout.SetText ("am"); @@ -285,12 +287,14 @@ } } - void MakeRectangularDigitalIcon (Context cr, int size) + void MakeRectangularDigitalIcon (DockySurface surface) { + Context cr = surface.Context; + // useful sizes - int timeSize = size / 3; - int dateSize = size / 4; - int ampmSize = size / 4; + int timeSize = surface.Height / 3; + int dateSize = surface.Height / 4; + int ampmSize = surface.Height / 4; int spacing = timeSize / 2; // shared by all text @@ -299,7 +303,7 @@ layout.FontDescription = new Gtk.Style().FontDescription; layout.FontDescription.Weight = Pango.Weight.Bold; layout.Ellipsize = Pango.EllipsizeMode.None; - layout.Width = Pango.Units.FromPixels (size); + layout.Width = Pango.Units.FromPixels (surface.Width); // draw the time, outlined @@ -316,7 +320,7 @@ int timeYOffset = timeSize / 2; if (!ShowDate) timeYOffset += timeSize / 2; - cr.MoveTo (size - inkRect.Width / 2, timeYOffset); + cr.MoveTo ((surface.Width - inkRect.Width) / 2, timeYOffset); Pango.CairoHelper.LayoutPath (cr, layout); cr.LineWidth = 2; @@ -331,7 +335,7 @@ layout.SetText (DateTime.Now.ToString ("MMM dd")); layout.GetPixelExtents (out inkRect, out logicalRect); - cr.MoveTo (size - inkRect.Width / 2, size - spacing - dateSize); + cr.MoveTo ((surface.Width - inkRect.Width) / 2, surface.Height - spacing - dateSize); Pango.CairoHelper.LayoutPath (cr, layout); cr.Color = new Cairo.Color (0, 0, 0, 0.5); @@ -352,7 +356,7 @@ int yOffset = timeSize; if (!ShowDate) yOffset += timeSize / 2; - cr.MoveTo (2 * size - logicalRect.Width, yOffset - inkRect.Height); + cr.MoveTo (surface.Width - logicalRect.Width, yOffset - inkRect.Height); Pango.CairoHelper.LayoutPath (cr, layout); cr.Color = new Cairo.Color (1, 1, 1, 0.8); @@ -418,19 +422,19 @@ protected override MenuList OnGetMenuItems () { MenuList list = base.OnGetMenuItems (); - list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("Di_gital Clock"), ShowDigital ? "gtk-apply" : "gtk-remove", (o, a) => + list[MenuListContainer.Actions].Add (new IconMenuItem (Catalog.GetString ("Di_gital Clock"), ShowDigital ? "gtk-apply" : "gtk-remove", (o, a) => { ShowDigital = !ShowDigital; QueueRedraw (); })); - list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("24-Hour _Clock"), ShowMilitary ? "gtk-apply" : "gtk-remove", (o, a) => + list[MenuListContainer.Actions].Add (new IconMenuItem (Catalog.GetString ("24-Hour _Clock"), ShowMilitary ? "gtk-apply" : "gtk-remove", (o, a) => { ShowMilitary = !ShowMilitary; QueueRedraw (); }, !ShowDigital)); - list[MenuListContainer.Actions].Add (new MenuItem (Catalog.GetString ("Show _Date"), ShowDate ? "gtk-apply" : "gtk-remove", (o, a) => + list[MenuListContainer.Actions].Add (new IconMenuItem (Catalog.GetString ("Show _Date"), ShowDate ? "gtk-apply" : "gtk-remove", (o, a) => { ShowDate = !ShowDate; QueueRedraw (); diff -Nru docky-2.0.2/StandardPlugins/GMail/gtk-gui/GMail.GMailLabelConfig.cs docky-2.0.4/StandardPlugins/GMail/gtk-gui/GMail.GMailLabelConfig.cs --- docky-2.0.2/StandardPlugins/GMail/gtk-gui/GMail.GMailLabelConfig.cs 2010-04-12 12:57:54.643650047 +0200 +++ docky-2.0.4/StandardPlugins/GMail/gtk-gui/GMail.GMailLabelConfig.cs 2010-05-25 13:09:17.687364090 +0200 @@ -128,7 +128,7 @@ w17.Expand = false; w17.Fill = false; // Container child hbox2.Gtk.Box+BoxChild - this.check_interval = new Gtk.SpinButton(2, 100, 1); + this.check_interval = new Gtk.SpinButton(2, 1440, 1); this.check_interval.CanFocus = true; this.check_interval.Name = "check_interval"; this.check_interval.Adjustment.PageIncrement = 10; diff -Nru docky-2.0.2/StandardPlugins/GMail/src/GMailAtom.cs docky-2.0.4/StandardPlugins/GMail/src/GMailAtom.cs --- docky-2.0.2/StandardPlugins/GMail/src/GMailAtom.cs 2010-04-12 15:03:31.793612502 +0200 +++ docky-2.0.4/StandardPlugins/GMail/src/GMailAtom.cs 2010-05-25 16:49:54.178614978 +0200 @@ -196,11 +196,14 @@ void CheckGMail () { - if (string.IsNullOrEmpty (GMailPreferences.User) || string.IsNullOrEmpty (GMailPreferences.Password)) { - OnGMailFailed (Catalog.GetString ("Username or Password not set")); + string password = GMailPreferences.Password; + if (string.IsNullOrEmpty (GMailPreferences.User) || string.IsNullOrEmpty (password)) { + Gtk.Application.Invoke (delegate { + OnGMailFailed (Catalog.GetString ("Username or Password not set")); + }); return; } - + checkerThread = DockServices.System.RunOnThread (() => { try { Gtk.Application.Invoke (delegate { OnGMailChecking (); }); @@ -217,7 +220,7 @@ HttpWebRequest request = (HttpWebRequest) WebRequest.Create (url); request.Timeout = 60000; request.UserAgent = DockServices.System.UserAgent; - request.Credentials = new NetworkCredential (GMailPreferences.User, GMailPreferences.Password); + request.Credentials = new NetworkCredential (GMailPreferences.User, password); if (DockServices.System.UseProxy) request.Proxy = DockServices.System.Proxy; // FIXME remove when ServicePointManager.ServerCertificateValidationCallback implemented in mono @@ -265,7 +268,7 @@ if (GMailPreferences.Notify) { if (NewCount > 5) - Log.Notify (CurrentLabel, "gmail", "You have {0} new, unread messages", NewCount); + Log.Notify (CurrentLabel, "gmail", Catalog.GetString ("You have {0} new, unread messages"), NewCount); else foreach (UnreadMessage message in tmp) if (message.SendDate > GMailPreferences.LastChecked) @@ -278,6 +281,8 @@ messages = tmp; Gtk.Application.Invoke (delegate { OnGMailChecked (); }); + } catch (ThreadAbortException) { + // do nothing } catch (NullReferenceException) { Gtk.Application.Invoke (delegate { OnGMailFailed (Catalog.GetString ("Feed Error")); diff -Nru docky-2.0.2/StandardPlugins/GMail/src/GMailDockItem.cs docky-2.0.4/StandardPlugins/GMail/src/GMailDockItem.cs --- docky-2.0.2/StandardPlugins/GMail/src/GMailDockItem.cs 2010-04-11 08:11:13.635305277 +0200 +++ docky-2.0.4/StandardPlugins/GMail/src/GMailDockItem.cs 2010-05-25 13:20:43.789601796 +0200 @@ -49,6 +49,22 @@ public static string DefaultLabel { get { return "Inbox"; } } + string BaseUrl { + get { + string[] login = GMailPreferences.User.Split (new char[] {'@'}); + string domain = login.Length > 1 ? login [1] : "gmail.com"; + string url = "https://mail.google.com/"; + + // add the domain + if (domain == "gmail.com" || domain == "googlemail.com") + url += "mail"; + else + url += "a/" + domain; + + return url; + } + } + GMailItemProvider parent; ConfigDialog config; @@ -134,21 +150,11 @@ surface.Context.PaintWithAlpha (.5); } } - + void OpenInbox () { - string[] login = GMailPreferences.User.Split (new char[] {'@'}); - string domain = login.Length > 1 ? login [1] : "gmail.com"; - string url = "https://mail.google.com/"; - - // add the domain - if (domain == "gmail.com" || domain == "googlemail.com") - url += "mail"; - else - url += "a/" + domain; + String url = BaseUrl + "/#"; - url += "/#"; - // going to a custom label if (Atom.CurrentLabel != DefaultLabel) url += "label/"; @@ -193,7 +199,7 @@ new MenuItem (Catalog.GetString ("_Compose Mail"), "mail-message-new", delegate { - DockServices.System.Open ("https://mail.google.com/mail/#compose"); + DockServices.System.Open (BaseUrl + "/#compose"); }), }; diff -Nru docky-2.0.2/StandardPlugins/NPR/src/Station.cs docky-2.0.4/StandardPlugins/NPR/src/Station.cs --- docky-2.0.2/StandardPlugins/NPR/src/Station.cs 2010-04-12 15:03:31.793612502 +0200 +++ docky-2.0.4/StandardPlugins/NPR/src/Station.cs 2010-05-28 16:49:50.255126135 +0200 @@ -1,5 +1,5 @@ // -// Copyright (C) 2009 Chris Szikszoy +// Copyright (C) 2009 Chris Szikszoy, Robert Dyer // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -65,23 +65,34 @@ { IsLoaded = false; Icon = DefaultLogo = "nprlogo.gif@" + GetType ().Assembly.FullName; + DockServices.System.ConnectionStatusChanged += HandleConnectionStatusChanged; + ID = id; - if (id > 0) { + if (ID > 0) { DockServices.System.RunOnThread (() => { - LoadDataFromXElement (NPR.StationXElement (id)); + LoadDataFromXElement (NPR.StationXElement (ID)); }); // this is how we create our "null" station entry } else { - ID = id; Name = Catalog.GetString ("No stations found."); Description = Catalog.GetString ("Please try your search again."); ShowActionButton = false; IsLoaded = true; } } + + void HandleConnectionStatusChanged (object o, EventArgs args) + { + DockServices.System.RunOnThread (() => { + LoadDataFromXElement (NPR.StationXElement (ID)); + }); + } void LoadDataFromXElement (XElement stationElement) { + if (!DockServices.System.NetworkConnected) + return; + IsSetUp = false; Name = stationElement.Element ("name").Value; @@ -97,18 +108,15 @@ string logo = stationElement.Elements ("image").First (el => el.Attribute ("type").Value == "logo").Value; GLib.File l = FileFactory.NewForUri (logo); LogoFile = System.IO.Path.Combine (System.IO.Path.GetTempPath (), l.Basename); - if (System.IO.File.Exists (LogoFile)) { - Finish (); - return; + if (!System.IO.File.Exists (LogoFile)) { + WebClient cl = new WebClient (); + cl.Headers.Add ("user-agent", DockServices.System.UserAgent); + if (DockServices.System.UseProxy) + cl.Proxy = DockServices.System.Proxy; + + cl.DownloadFile (logo, LogoFile); } - WebClient cl = new WebClient (); - cl.Headers.Add ("user-agent", DockServices.System.UserAgent); - if (DockServices.System.UseProxy) - cl.Proxy = DockServices.System.Proxy; - - cl.DownloadFile (logo, LogoFile); - Finish (); } @@ -173,5 +181,10 @@ }); } + public override void Dispose () + { + DockServices.System.ConnectionStatusChanged -= HandleConnectionStatusChanged; + base.Dispose (); + } } } diff -Nru docky-2.0.2/StandardPlugins/NPR/src/StationDockItem.cs docky-2.0.4/StandardPlugins/NPR/src/StationDockItem.cs --- docky-2.0.2/StandardPlugins/NPR/src/StationDockItem.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/StandardPlugins/NPR/src/StationDockItem.cs 2010-05-28 16:49:50.266377057 +0200 @@ -1,5 +1,5 @@ // -// Copyright (C) 2009 Jason Smith +// Copyright (C) 2009 Jason Smith, Robert Dyer // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -29,10 +29,8 @@ namespace NPR { - public class StationDockItem : IconDockItem { - public Station OwnedStation; static ConfigDialog config; @@ -176,5 +174,11 @@ config = new NPRConfigDialog (); config.Show (); } + + public override void Dispose () + { + OwnedStation.Dispose (); + base.Dispose (); + } } } diff -Nru docky-2.0.2/StandardPlugins/RecentDocuments/src/RecentDocumentsItem.cs docky-2.0.4/StandardPlugins/RecentDocuments/src/RecentDocumentsItem.cs --- docky-2.0.2/StandardPlugins/RecentDocuments/src/RecentDocumentsItem.cs 2010-03-16 09:38:16.274065379 +0100 +++ docky-2.0.4/StandardPlugins/RecentDocuments/src/RecentDocumentsItem.cs 2010-05-25 13:11:18.425680210 +0200 @@ -105,14 +105,16 @@ void UpdateInfo () { - if (RecentDocs.Count() == 0) { - CurrentFile = null; - return; + lock (RecentDocs) { + if (RecentDocs.Count() == 0) { + CurrentFile = null; + return; + } + + if (CurrentFile == null || RecentDocs.IndexOf (CurrentFile) == -1) + CurrentFile = RecentDocs.First (); } - if (CurrentFile == null || RecentDocs.IndexOf (CurrentFile) == -1) - CurrentFile = RecentDocs.First (); - Icon = CurrentFile.Icon; HoverText = CurrentFile.HoverText; QueueRedraw (); @@ -153,14 +155,16 @@ { MenuList list = base.OnGetMenuItems (); - foreach (FileDockItem _f in RecentDocs) { - FileDockItem f = _f; - if (!f.OwnedFile.Exists) - continue; + lock (RecentDocs) { + foreach (FileDockItem _f in RecentDocs) { + FileDockItem f = _f; + if (!f.OwnedFile.Exists) + continue; - MenuItem item = new IconMenuItem (f.OwnedFile.Basename, f.Icon, (o, a) => DockServices.System.Open (f.OwnedFile)); - item.Mnemonic = null; - list[MenuListContainer.RelatedItems].Add (item); + MenuItem item = new IconMenuItem (f.OwnedFile.Basename, f.Icon, (o, a) => DockServices.System.Open (f.OwnedFile)); + item.Mnemonic = null; + list[MenuListContainer.RelatedItems].Add (item); + } } // check to make sure our right click menu has the same number of items as RecentDocs diff -Nru docky-2.0.2/StandardPlugins/Trash/src/TrashDockItem.cs docky-2.0.4/StandardPlugins/Trash/src/TrashDockItem.cs --- docky-2.0.2/StandardPlugins/Trash/src/TrashDockItem.cs 2010-04-11 08:04:53.627856299 +0200 +++ docky-2.0.4/StandardPlugins/Trash/src/TrashDockItem.cs 2010-05-25 19:00:18.626114291 +0200 @@ -46,6 +46,10 @@ } } + public override string DropText { + get { return Catalog.GetString ("Drop to move to Trash"); } + } + FileMonitor TrashMonitor { get; set; } public File OwnedFile { get; private set; } diff -Nru docky-2.0.2/StandardPlugins/Weather/src/WeatherPreferences.cs docky-2.0.4/StandardPlugins/Weather/src/WeatherPreferences.cs --- docky-2.0.2/StandardPlugins/Weather/src/WeatherPreferences.cs 2010-02-14 19:56:42.000000000 +0100 +++ docky-2.0.4/StandardPlugins/Weather/src/WeatherPreferences.cs 2010-05-25 13:08:44.657363552 +0200 @@ -53,7 +53,11 @@ /// public static string Source { get { return prefs.Get (SourceKey, WunderWeatherSource.GetInstance ().Name); } - set { prefs.Set (SourceKey, value); OnSourceChanged (); } + set { + if (value == Source) return; + prefs.Set (SourceKey, value); + OnSourceChanged (); + } } /// @@ -75,7 +79,11 @@ /// public static string[] Location { get { return prefs.Get (LocationKey, new string[] {"50014"}); } - set { prefs.Set (LocationKey, value); OnLocationChanged (); } + set { + if (value == Location) return; + prefs.Set (LocationKey, value); + OnLocationChanged (); + } } /// @@ -97,7 +105,11 @@ /// public static uint Timeout { get { return (uint) prefs.Get (TimeoutKey, 30); } - set { prefs.Set (TimeoutKey, (int) value); OnTimeoutChanged (); } + set { + if (value == Timeout) return; + prefs.Set (TimeoutKey, (int) value); + OnTimeoutChanged (); + } } /// @@ -124,7 +136,11 @@ if (!MetricDefault.HasValue) MetricDefault = RegionInfo.CurrentRegion != null && RegionInfo.CurrentRegion.IsMetric; return prefs.Get (MetricKey, false); } - set { prefs.Set (MetricKey, value); OnMetricChanged (); } + set { + if (value == Metric) return; + prefs.Set (MetricKey, value); + OnMetricChanged (); + } } } }