[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