diff --git a/qubes_rpc/qvm-copy-to-vm.gnome b/qubes_rpc/qvm-copy-to-vm.gnome
index cb2b86e5..e6c6c70d 100755
--- a/qubes_rpc/qvm-copy-to-vm.gnome
+++ b/qubes_rpc/qvm-copy-to-vm.gnome
@@ -20,7 +20,7 @@
 #
 #
 
-VM=$(zenity --entry --title="File Copy" --text="Enter the destination domain name:")
+VM=$(qvm-mru-entry --title="File Copy" --text="Enter the destination domain name:" --mrufile "qvm-mru-filecopy")
 if [ X$VM = X ] ; then exit 0 ; fi
 
 SIZE=$(du --apparent-size -c "$@" | tail -1 | cut -f 1)
diff --git a/qubes_rpc/qvm-mru-entry b/qubes_rpc/qvm-mru-entry
new file mode 100755
index 00000000..b516753c
--- /dev/null
+++ b/qubes_rpc/qvm-mru-entry
@@ -0,0 +1,165 @@
+#!/usr/bin/python
+#
+# The Qubes OS Project, http://www.qubes-os.org
+#
+# Copyright (C) 2012 Bruce Downs <bruceadowns@gmail.com>
+#
+# 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 Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+#
+import os
+from optparse import OptionParser
+import gtk
+
+class QubesMruDialog(gtk.Dialog):
+    entry = None
+    mrufile = None
+
+    def __init__(self, title, text, mrufile):
+        self.mrufile = mrufile
+
+        gtk.Dialog.__init__(
+            self,
+            title,
+            None,
+            0,
+            (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
+             gtk.STOCK_OK, gtk.RESPONSE_OK))
+
+        # setting the default response to 'ok'
+        # does not work as advertised
+        # using key-press-event instead
+        #self.set_default_response(gtk.RESPONSE_OK)
+        
+        self.connect("destroy", lambda *w: gtk.main_quit())
+        self.connect("response", self.response_callback)
+        self.connect("key-press-event", self.key_press_callback)
+
+        self.set_position(gtk.WIN_POS_CENTER)
+        self.set_resizable(True)
+
+        vbox = gtk.VBox(True, 5)
+        self.vbox.pack_start(vbox, True, True, 0)
+        vbox.set_border_width(5)
+
+        label = gtk.Label()
+        label.set_markup(text)
+        vbox.pack_start(label, False, False, 0)
+
+        # Create our entry
+        self.entry = gtk.Entry()
+        vbox.pack_start(self.entry, False, False, 0)
+
+        # Create the completion object
+        completion = gtk.EntryCompletion()
+
+        # Assign the completion to the entry
+        self.entry.set_completion(completion)
+
+        # Create a tree model and use it as the completion model
+        completion_model, firstline = self.create_completion_model()
+        completion.set_model(completion_model)
+
+        # Use model column 0 as the text column
+        completion.set_text_column(0)
+
+        if firstline:
+            self.entry.set_text(firstline)
+
+        self.show_all()
+
+    def create_completion_model(self):
+        store = gtk.ListStore(str)
+        firstline = None
+
+        if self.mrufile and os.access(self.mrufile, os.R_OK):
+            # read lines from mru file
+            lines = [line.strip() for line in open(self.mrufile)]
+            for line in lines:
+                if not firstline:
+                    firstline = line
+
+                iter = store.append()
+                store.set(iter, 0, line)
+
+        return store, firstline
+
+    def handle_ok(self):
+        my_entry = self.entry.get_text()
+
+        if len(my_entry) > 0:
+            linesorg = []
+            linesorg.insert(0, my_entry)
+
+            # calc mru lines
+            if os.access(self.mrufile, os.R_OK):
+                # read lines from existing mru file
+                fMru = open(self.mrufile, "r")
+                linesorg += [line.strip() for line in fMru]
+                fMru.close()
+
+            #uniqify
+            linesuniq = []
+            for lineuniq in linesorg:
+                if (len(lineuniq) > 0 and lineuniq not in linesuniq):
+                    linesuniq.append(lineuniq)
+
+            # write to mru
+            # up to 50 unique
+            fMru = file(self.mrufile, "w")
+            fMru.writelines( "%s\n" % line for line in linesuniq[:50] )
+            fMru.close()
+
+        # print entry to stdout
+        print my_entry
+
+    def response_callback(self, button, response_id):
+        if response_id == gtk.RESPONSE_OK:
+            self.handle_ok()
+        self.destroy()
+
+    def key_press_callback(self, button, event):
+        if event.keyval == gtk.keysyms.Return:
+            self.handle_ok()
+            self.destroy()
+
+def main():
+    usage = "usage: %prog [--title 'Qubes Title'] [--text 'Qubes Text'] [--mrufile 'mru file name']"
+    parser = OptionParser (usage)
+    parser.add_option ("-l", "--title",
+                       action="store",
+                       dest="title",
+                       default="Qubes MRU Dialog Entry",
+                       help="Set the dialog title [%default]")
+    parser.add_option ("-x", "--text",
+                       action="store",
+                       dest="text",
+                       default="Enter Qubes text:",
+                       help="Set the dialog text [%default]")
+    parser.add_option ("-f", "--mrufile",
+                       action="store",
+                       dest="mrufile",
+                       default='qvm-mru',
+                       help="MRU file name [%default]")
+    (options, args) = parser.parse_args ()
+
+    mrudir = os.path.expanduser('~') + os.sep + '.config'
+    if not os.path.exists(mrudir):
+        os.makedirs(mrudir)
+    QubesMruDialog(options.title, options.text, mrudir + os.sep + options.mrufile)
+    gtk.main()
+
+main()
+
diff --git a/rpm_spec/core-vm.spec b/rpm_spec/core-vm.spec
index f1a5e5dc..72bf87a8 100644
--- a/rpm_spec/core-vm.spec
+++ b/rpm_spec/core-vm.spec
@@ -153,7 +153,7 @@ install network/qubes_netwatcher $RPM_BUILD_ROOT/usr/sbin/
 
 install -d $RPM_BUILD_ROOT/usr/bin
 
-install qubes_rpc/{qvm-open-in-dvm,qvm-open-in-vm,qvm-copy-to-vm,qvm-run} $RPM_BUILD_ROOT/usr/bin
+install qubes_rpc/{qvm-open-in-dvm,qvm-open-in-vm,qvm-copy-to-vm,qvm-run,qvm-mru-entry} $RPM_BUILD_ROOT/usr/bin
 install qubes_rpc/wrap_in_html_if_url.sh $RPM_BUILD_ROOT/usr/lib/qubes
 install qubes_rpc/qvm-copy-to-vm.kde $RPM_BUILD_ROOT/usr/lib/qubes
 install qubes_rpc/qvm-copy-to-vm.gnome $RPM_BUILD_ROOT/usr/lib/qubes
@@ -393,6 +393,7 @@ rm -rf $RPM_BUILD_ROOT
 /usr/bin/qvm-open-in-dvm
 /usr/bin/qvm-open-in-vm
 /usr/bin/qvm-run
+/usr/bin/qvm-mru-entry
 /usr/bin/xenstore-watch-qubes
 %dir /usr/lib/qubes
 /usr/lib/qubes/block_add_change