[Pkg-cli-apps-commits] [SCM] keepass2 branch, master, updated. debian/2.18+dfsg-1-2-g106ef26

Julian Taylor jtaylor.debian at googlemail.com
Sun Jan 15 11:49:13 UTC 2012


The following commit has been merged in the master branch:
commit 106ef26c528ce6617cec08c5721032004048e15a
Author: Julian Taylor <jtaylor.debian at googlemail.com>
Date:   Sun Jan 15 12:48:37 2012 +0100

    add patch for broken event ordering in mono 2.10

diff --git a/debian/changelog b/debian/changelog
index cae9ee8..e83b128 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+keepass2 (2.18+dfsg-2) UNRELEASED; urgency=low
+
+  * add patch for broken event ordering in mono 2.10
+
+ -- Julian Taylor <jtaylor.debian at googlemail.com>  Sun, 15 Jan 2012 12:47:52 +0100
+
 keepass2 (2.18+dfsg-1) unstable; urgency=low
 
   * New upstream release
diff --git a/debian/patches/fix-winforms-eventordering.patch b/debian/patches/fix-winforms-eventordering.patch
new file mode 100644
index 0000000..37d8e59
--- /dev/null
+++ b/debian/patches/fix-winforms-eventordering.patch
@@ -0,0 +1,279 @@
+From: Dominik Reichl <dominik.reichl at t-online.de>
+Date: Thu, 12 Jan 2012 19:59:59 +0100
+Subject: workaround broken event ordering in mono 2.10
+
+Bug: http://bugzilla.xamarin.com/show_bug.cgi?id=2159
+---
+ KeePass/Forms/PwEntryForm.cs      |    9 ++
+ KeePass/KeePass.csproj            |    1 +
+ KeePass/UI/GlobalWindowManager.cs |    5 +
+ KeePass/Util/MonoWorkarounds.cs   |  205 +++++++++++++++++++++++++++++++++++++
+ 4 files changed, 220 insertions(+), 0 deletions(-)
+ create mode 100644 KeePass/Util/MonoWorkarounds.cs
+
+--- a/KeePass/Forms/PwEntryForm.cs
++++ b/KeePass/Forms/PwEntryForm.cs
+@@ -1609,8 +1609,17 @@
+ 			return base.ProcessDialogKey(keyData);
+ 		}
+ 
++		private bool m_bClosing = false; // Mono bug workaround
+ 		private void OnFormClosing(object sender, FormClosingEventArgs e)
+ 		{
++			if(m_bClosing) return;
++			m_bClosing = true;
++			HandleFormClosing(e);
++			m_bClosing = false;
++		}
++
++		private void HandleFormClosing(FormClosingEventArgs e)
++		{
+ 			bool bCancel = false;
+ 			if(!m_bForceClosing && (m_pwEditMode != PwEditMode.ViewReadOnlyEntry))
+ 			{
+--- a/KeePass/KeePass.csproj
++++ b/KeePass/KeePass.csproj
+@@ -973,6 +973,7 @@
+     <Compile Include="Util\IpcBroadcast.Fsw.cs" />
+     <Compile Include="Util\IpcUtilEx.cs" />
+     <Compile Include="Util\KeyUtil.cs" />
++    <Compile Include="Util\MonoWorkarounds.cs" />
+     <Compile Include="Util\NetUtil.cs" />
+     <Compile Include="Util\PwGeneratorUtil.cs" />
+     <Compile Include="Util\SearchUtil.cs" />
+--- a/KeePass/UI/GlobalWindowManager.cs
++++ b/KeePass/UI/GlobalWindowManager.cs
+@@ -25,6 +25,7 @@
+ using System.Drawing;
+ 
+ using KeePass.App;
++using KeePass.Util;
+ 
+ using KeePassLib.Native;
+ using KeePassLib.Utility;
+@@ -122,6 +123,8 @@
+ 
+ 			CustomizeControl(form);
+ 
++			MonoWorkarounds.ApplyTo(form);
++
+ 			if(GlobalWindowManager.WindowAdded != null)
+ 				GlobalWindowManager.WindowAdded(null, new GwmWindowEventArgs(
+ 					form, wnd));
+@@ -148,6 +151,8 @@
+ 						GlobalWindowManager.WindowRemoved(null, new GwmWindowEventArgs(
+ 							form, m_vWindows[i].Value));
+ 
++					MonoWorkarounds.Release(form);
++
+ 					m_vWindows.RemoveAt(i);
+ 					return;
+ 				}
+--- /dev/null
++++ b/KeePass/Util/MonoWorkarounds.cs
+@@ -0,0 +1,205 @@
++/*
++  KeePass Password Safe - The Open-Source Password Manager
++  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl at t-online.de>
++
++  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 2 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, write to the Free Software
++  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++*/
++
++using System;
++using System.Collections.Generic;
++using System.Text;
++using System.Windows.Forms;
++using System.ComponentModel;
++using System.Reflection;
++using System.Diagnostics;
++
++using KeePassLib.Native;
++
++namespace KeePass.Util
++{
++	public static class MonoWorkarounds
++	{
++		private static bool? m_bReq = null;
++		public static bool IsRequired
++		{
++			get
++			{
++				if(!m_bReq.HasValue) m_bReq = NativeLib.IsUnix();
++				return m_bReq.Value;
++			}
++		}
++
++		public static void ApplyTo(Form f)
++		{
++			if(!MonoWorkarounds.IsRequired) return;
++			if(f == null) { Debug.Assert(false); return; }
++
++			ApplyToControlsRec(f.Controls, f, MonoWorkarounds.ApplyToControl);
++		}
++
++		public static void Release(Form f)
++		{
++			if(!MonoWorkarounds.IsRequired) return;
++			if(f == null) { Debug.Assert(false); return; }
++
++			ApplyToControlsRec(f.Controls, f, MonoWorkarounds.ReleaseControl);
++		}
++
++		private delegate void MwaControlHandler(Control c, Form fContext);
++
++		private static void ApplyToControlsRec(Control.ControlCollection cc,
++			Form fContext, MwaControlHandler fn)
++		{
++			if(cc == null) { Debug.Assert(false); return; }
++
++			foreach(Control c in cc)
++			{
++				fn(c, fContext);
++				ApplyToControlsRec(c.Controls, fContext, fn);
++			}
++		}
++
++		private sealed class MwaHandlerInfo
++		{
++			private readonly Delegate m_fnOrg; // May be null
++			public Delegate FunctionOriginal
++			{
++				get { return m_fnOrg; }
++			}
++
++			private readonly Delegate m_fnOvr;
++			public Delegate FunctionOverride
++			{
++				get { return m_fnOvr; }
++			}
++
++			private readonly DialogResult m_dr;
++			public DialogResult Result
++			{
++				get { return m_dr; }
++			}
++
++			private readonly Form m_fContext;
++			public Form FormContext
++			{
++				get { return m_fContext; }
++			}
++
++			public MwaHandlerInfo(Delegate fnOrg, Delegate fnOvr, DialogResult dr,
++				Form fContext)
++			{
++				m_fnOrg = fnOrg;
++				m_fnOvr = fnOvr;
++				m_dr = dr;
++				m_fContext = fContext;
++			}
++		}
++
++		private static void ApplyToControl(Control c, Form fContext)
++		{
++			Button btn = (c as Button);
++			if(btn != null) ApplyToButton(btn, fContext);
++		}
++
++		private static EventHandlerList GetEventHandlers(Component c,
++			out object objClickEvent)
++		{
++			FieldInfo fi = typeof(Control).GetField("ClickEvent", // Mono
++				BindingFlags.Static | BindingFlags.NonPublic);
++			if(fi == null)
++				fi = typeof(Control).GetField("EventClick", // .NET
++					BindingFlags.Static | BindingFlags.NonPublic);
++			if(fi == null) { Debug.Assert(false); objClickEvent = null; return null; }
++
++			objClickEvent = fi.GetValue(null);
++			if(objClickEvent == null) { Debug.Assert(false); return null; }
++
++			PropertyInfo pi = typeof(Component).GetProperty("Events",
++				BindingFlags.Instance | BindingFlags.NonPublic);
++			return (pi.GetValue(c, null) as EventHandlerList);
++		}
++
++		private static Dictionary<object, MwaHandlerInfo> m_dictHandlers =
++			new Dictionary<object, MwaHandlerInfo>();
++		private static void ApplyToButton(Button btn, Form fContext)
++		{
++			DialogResult dr = btn.DialogResult;
++			if(dr == DialogResult.None) return; // No workaround required
++
++			object objClickEvent;
++			EventHandlerList ehl = GetEventHandlers(btn, out objClickEvent);
++			if(ehl == null) { Debug.Assert(false); return; }
++			Delegate fnClick = ehl[objClickEvent]; // May be null
++
++			EventHandler fnOvr = new EventHandler(MonoWorkarounds.OnButtonClick);
++			m_dictHandlers[btn] = new MwaHandlerInfo(fnClick, fnOvr, dr, fContext);
++			btn.DialogResult = DialogResult.None;
++			ehl[objClickEvent] = fnOvr;
++		}
++
++		private static void ReleaseControl(Control c, Form fContext)
++		{
++			Button btn = (c as Button);
++			if(btn != null) ReleaseButton(btn, fContext);
++		}
++
++		private static void ReleaseButton(Button btn, Form fContext)
++		{
++			MwaHandlerInfo hi;
++			m_dictHandlers.TryGetValue(btn, out hi);
++			if(hi == null) return;
++
++			object objClickEvent;
++			EventHandlerList ehl = GetEventHandlers(btn, out objClickEvent);
++			if(ehl == null) { Debug.Assert(false); return; }
++
++			if(hi.FunctionOriginal != null)
++				ehl[objClickEvent] = hi.FunctionOriginal;
++			else ehl.RemoveHandler(objClickEvent, hi.FunctionOverride);
++
++			btn.DialogResult = hi.Result;
++			m_dictHandlers.Remove(btn);
++		}
++
++		private static void OnButtonClick(object sender, EventArgs e)
++		{
++			Button btn = (sender as Button);
++			if(btn == null) { Debug.Assert(false); return; }
++
++			MwaHandlerInfo hi;
++			m_dictHandlers.TryGetValue(btn, out hi);
++			if(hi == null) { Debug.Assert(false); return; }
++
++			Form f = hi.FormContext;
++
++			// Set current dialog result by setting the form's private
++			// variable; the DialogResult property can't be used,
++			// because it raises close events
++			FieldInfo fiRes = typeof(Form).GetField("dialog_result",
++				BindingFlags.Instance | BindingFlags.NonPublic);
++			if(fiRes == null) { Debug.Assert(false); return; }
++			if(f != null) fiRes.SetValue(f, hi.Result);
++
++			if(hi.FunctionOriginal != null)
++				hi.FunctionOriginal.Method.Invoke(hi.FunctionOriginal.Target,
++					new object[]{ btn, e });
++
++			// Raise close events, if the click event handler hasn't
++			// reset the dialog result
++			if((f != null) && (f.DialogResult == hi.Result))
++				f.DialogResult = hi.Result; // Raises close events
++		}
++	}
++}
diff --git a/debian/patches/series b/debian/patches/series
index 8e07c9a..865a26e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -7,3 +7,4 @@ remove-ToolsVersion-3.5.patch
 enable-local-help.patch
 work-around-issues-with-autotype-and-keyboard-layout.patch
 disable-autoupdate-dialog.patch
+fix-winforms-eventordering.patch

-- 
keepass2



More information about the Pkg-cli-apps-commits mailing list