Re: Opening new tabs in existing instance



Le 17/10/2011 13:23, Kai a écrit :
On 14 October 2011 22:02, Magnus Ihse Bursie
<magnus ihse bursie oracle com>  wrote:
When I started investigating this, I found out that a patch to fix this has
already been written, but never been included. See
https://bugzilla.gnome.org/show_bug.cgi?id=453670. It's a bit old, and I'm
not sure if it works in a current meld.
> From a very quick look, there's no way that will apply, but I think it
can probably be made to work.
the chances that such a patch would get included? If the chances are
high enough, I'm more than willing to fix the patch so it works on the
current source base.
The chances that something similar to that patch would get in are
good, but the approach is overly-simplistic. For example, I know
people with workflows that require multiple Meld windows, and that
patch would break those. Off the top of my head, I think we'd at least
need support for a command-line choice between opening new tabs and
starting a new process.

More generally speaking, we definitely want some kind of dbus
interface. Getting that code working is also relatively simple.
However, any interface we add would risk becoming an ABI that we'd
have to maintain, so it would be good to get it right.
Hi,

I've maintained Kacper Wysocki 's adapted patch and used it successfully since v1.3.1-1
Cf https://bugzilla.gnome.org/show_bug.cgi?id=616466

Please find attached successive patches:
meldapp.1.3.2-1_option--newtab.patch
meldapp.1.3.2-2_option--newtab.patch
meldapp.1.4.0-2_option--newtab.patch
meldapp.1.5.0_option--newtab.patch
meldapp.1.5.1-1_option--newtab.patch
meldapp.1.5.2-1_option--newtab.patch

I also attach one I currently use at that time for switching to appropriate workspace, but which rely on GNU/linux wmctrl tool:
meldapp.1.5.2-1_option--newtab+wmctrl.patch

I can re-open a new bugzilla if you need me and I remain at your disposal for any testing
thanks again for this great app !
cheers
Antoine
--- meld.1.3.2-1.HACK	2010-09-29 15:04:34.521113991 +0200
+++ meld.1.3.2-1.HACK	2010-09-29 15:05:18.448113989 +0200
@@ -110,10 +110,78 @@
 gtk.glade.textdomain("meld")
 gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
 
+#
+# DbusHandler
+#
+# optional
+# dbus Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_new_tab(self, rawargs):
+        self.app.parse_args(rawargs)
+        
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_new_tab(self, rawargs):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        return iface.open_new_tab(rawargs)
+
+#
+# main DbusHandled
+#
 def main():
     import meld.meldapp
     app = meld.meldapp.MeldApp()
-    app.parse_args(sys.argv[1:])
+
+    # new tab if running dbus registered instance
+    dbus_app = DBusApp()
+    running = False
+    if dbus_available:
+        running = dbus_app.running_already()
+        if running:
+            dbus_app.remote_open_new_tab(sys.argv[1:])
+            return
+    
+    # dbus register and run instance
+    if dbus_available and not running:
+        dbus_app.register(app)
+    try:
+        app.parse_args(sys.argv[1:])
+    except:
+        sys.exit(2)
     gtk.main()
 
 if profiling:
--- meld.1.3.2-2.HACK	2010-09-29 15:04:34.521113991 +0200
+++ meld.1.3.2-2.HACK	2010-09-29 15:05:18.448113989 +0200
@@ -110,10 +110,78 @@
 gtk.glade.textdomain("meld")
 gtk.icon_theme_get_default().append_search_path(meld.paths.icon_dir())
 
+#
+# DbusHandler
+#
+# optional
+# dbus Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_new_tab(self, rawargs):
+        self.app.parse_args(rawargs)
+        
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_new_tab(self, rawargs):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        return iface.open_new_tab(rawargs)
+
+#
+# main DbusHandled
+#
 def main():
     import meld.meldapp
     app = meld.meldapp.MeldApp()
-    app.parse_args(sys.argv[1:])
+
+    # new tab if running dbus registered instance
+    dbus_app = DBusApp()
+    running = False
+    if dbus_available:
+        running = dbus_app.running_already()
+        if running:
+            dbus_app.remote_open_new_tab(sys.argv[1:])
+            return
+    
+    # dbus register and run instance
+    if dbus_available and not running:
+        dbus_app.register(app)
+    try:
+        app.parse_args(sys.argv[1:])
+    except:
+        sys.exit(2)
     gtk.main()
 
 if profiling:
--- meldapp.py	2011-02-19 18:25:23.000000000 +0100
+++ meldapp.1.4.0-2.HACK.py	2011-03-10 21:40:35.000000000 +0100
@@ -51,6 +51,73 @@
 
 ################################################################################
 #
+# DbusHandler
+#
+################################################################################
+
+
+# optional
+# dbus Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_new_paths(self, args, auto_compare):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        #~ return iface.open_new_paths(args, auto_compare)
+        iface.open_new_paths(args, auto_compare)
+        #~ try:
+            #~ iface.open_new_paths(args, auto_compare)
+        #~ except:
+            #~ sys.stderr.write("%s: error: %s\n" % ("DBusApp :: remote_open_new_paths", sys.exc_info()[0]))
+            #~ raise
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_new_paths(self, args, auto_compare):
+        self.app.open_paths(args, auto_compare)
+        #~ try:
+            #~ self.app.open_paths(args, auto_compare)
+        #~ except:
+            #~ sys.stderr.write("%s: error: %s\n" % ("DBusProvider :: open_new_paths", sys.exc_info()[0]))
+            #~ raise
+        
+
+################################################################################
+#
 # NewDocDialog
 #
 ################################################################################
@@ -602,6 +669,8 @@
             version="%prog " + version)
         parser.add_option("-L", "--label", action="append", default=[],
             help=_("Set label to use instead of file name"))
+        parser.add_option("-n", "--newtab", action="store_true", default=False,
+            help=_("Open a new tab in already running instance"))
         parser.add_option("-a", "--auto-compare", action="store_true", default=False,
             help=_("Automatically compare all differing files on startup"))
         parser.add_option("-u", "--unified", action="store_true", help=_("Ignored for compatibility"))
@@ -618,7 +687,31 @@
         for files in options.diff:
             self.append_diff(files)
 
+        # DbusHandling
+        dbus_app = DBusApp()
+        running = False
+        if dbus_available:
+            #~ parser.error(_("DEBUG: dbus_available"))
+            running = dbus_app.running_already()
+            if running:
+                #~ parser.error(_("DEBUG: dbus_available and running"))
+                if options.newtab:
+                    #~ parser.error(_("DEBUG: dbus_available and running and --newtab"))
+                    tab = dbus_app.remote_open_new_paths(args, options.auto_compare)
+                    self.parse_args_tab(tab, options)
+                    sys.exit(0)
+        
+        # dbus register before running it
+        if dbus_available and not running:
+            #~ parser.error(_("DEBUG: dbus_available and not running"))
+            dbus_app.register(self)
+            
         tab = self.open_paths(args, options.auto_compare)
+        self.parse_args_tab(tab, options)
+
+    def parse_args_tab(self, tab, options):
         if tab:
             tab.set_labels(options.label)
 
--- meldapp.py	2010-12-26 23:10:50.000000000 +0100
+++ meldapp.1.5.HACK.py	2011-03-10 21:26:44.743344001 +0100
@@ -43,6 +43,59 @@
 
 ################################################################################
 #
+# DbusHandler
+#
+################################################################################
+
+# optional
+# dbus Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_new_paths(self, args, auto_compare):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        iface.open_new_paths(args, auto_compare)
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_new_paths(self, args, auto_compare):
+        self.app.open_paths(args, auto_compare)        
+
+
+################################################################################
+#
 # NewDocDialog
 #
 ################################################################################
@@ -614,6 +667,8 @@
             version="%prog " + version)
         parser.add_option("-L", "--label", action="append", default=[],
             help=_("Set label to use instead of file name"))
+        parser.add_option("-n", "--newtab", action="store_true", default=False,
+            help=_("Open a new tab in already running instance"))
         parser.add_option("-a", "--auto-compare", action="store_true", default=False,
             help=_("Automatically compare all differing files on startup"))
         parser.add_option("-o", "--output", action="store", type="string",
@@ -629,7 +684,25 @@
         for files in options.diff:
             self.open_paths(files)
 
+        # DbusHandling
+        dbus_app = DBusApp()
+        running = False
+        if dbus_available:
+            running = dbus_app.running_already()
+            if running:
+                if options.newtab:
+                    tab = dbus_app.remote_open_new_paths(args, options.auto_compare)
+                    self.parse_args_tab(tab, options)
+                    sys.exit(0)
+        
+        # dbus register before running it
+        if dbus_available and not running:
+            dbus_app.register(self)
+            
         tab = self.open_paths(args, options.auto_compare)
+        self.parse_args_tab(tab, options)
+
+    def parse_args_tab(self, tab, options):
         if tab:
             tab.set_labels(options.label)
 
--- meldapp.py 
+++ meldapp.1.5.1-1.HACK.py 
@@ -28,6 +28,59 @@
 import preferences
 
 version = "1.5.1"
+
+################################################################################
+#
+# DbusHandler
+#
+################################################################################
+import sys
+
+# optional
+# dbus Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_new_paths(self, args, auto_compare):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        iface.open_new_paths(args, auto_compare)
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_new_paths(self, args, auto_compare):
+        self.app.open_paths(args, auto_compare)        
 
 
 class FilterEntry(object):
@@ -164,6 +217,8 @@
             version="%prog " + version)
         parser.add_option("-L", "--label", action="append", default=[],
             help=_("Set label to use instead of file name"))
+        parser.add_option("-n", "--newtab", action="store_true", default=False,
+            help=_("Open a new tab in already running instance"))
         parser.add_option("-a", "--auto-compare", action="store_true", default=False,
             help=_("Automatically compare all differing files on startup"))
         parser.add_option("-o", "--output", action="store", type="string",
@@ -179,7 +234,25 @@
         for files in options.diff:
             self.open_paths(files)
 
+        if options.newtab:
+        # DbusHandling
+            dbus_app = DBusApp()
+            running = False
+            if dbus_available:
+                running = dbus_app.running_already()
+                if not running:
+                # dbus register it
+                    dbus_app.register(self)
+                else:
+                # use existing instance
+                    tab = dbus_app.remote_open_new_paths(args, options.auto_compare)
+                    self.parse_args_tab(tab, options)
+                    sys.exit(0)
+            
         tab = self.open_paths(args, options.auto_compare)
+        self.parse_args_tab(tab, options)
+
+    def parse_args_tab(self, tab, options):
         if tab:
             tab.set_labels(options.label)
 
=== modified file 'meldapp.py'
--- a/meld/meldapp.py
+++ b/meld/meldapp.py
@@ -28,6 +28,58 @@
 import preferences
 
 version = "1.5.2"
+
+################################################################################
+#
+# DbusHandler for --newtab option
+#
+################################################################################
+import sys
+
+# dbus check Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_paths(self, args, auto_compare):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        iface.open_paths(args, auto_compare)
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_paths(self, args, auto_compare):
+        self.app.window.open_paths(args, auto_compare)        
 
 
 class FilterEntry(object):
@@ -164,6 +216,8 @@
             version="%prog " + version)
         parser.add_option("-L", "--label", action="append", default=[],
             help=_("Set label to use instead of file name"))
+        parser.add_option("-n", "--newtab", action="store_true", default=False,
+            help=_("Open a new tab in already running instance"))
         parser.add_option("-a", "--auto-compare", action="store_true", default=False,
             help=_("Automatically compare all differing files on startup"))
         parser.add_option("-u", "--unified", action="store_true",
@@ -185,7 +239,28 @@
                 parser.error(_("can't compare more than three directories"))
             self.window.open_paths(files)
 
+        # dbus handling
+        if options.newtab:
+            dbus_app = DBusApp()
+            running_already = False
+            # if successfull import dbus
+            if dbus_available:
+                # check any already registered instance
+                running_already = dbus_app.running_already()
+                if not running_already:
+                # dbus register it
+                    dbus_app.register(self)
+                else:
+                # use existing instance
+                    tab = dbus_app.remote_open_paths(args, options.auto_compare)
+                    # open new tab and exit
+                    self.parse_args_tab(tab, options)
+                    sys.exit(0)
+            
         tab = self.window.open_paths(args, options.auto_compare)
+        self.parse_args_tab(tab, options)
+
+    def parse_args_tab(self, tab, options):
         if tab:
             tab.set_labels(options.label)
 
=== modified file 'meldapp.py'
--- a/meld/meldapp.py
+++ b/meld/meldapp.py
@@ -28,6 +28,61 @@
 import preferences
 
 version = "1.5.2"
+
+################################################################################
+#
+# DbusHandler for --newtab option
+#
+################################################################################
+import sys
+
+# dbus check Cf https://bugzilla.gnome.org/show_bug.cgi?id=453670
+dbus_available = False
+try:
+    import dbus
+    import dbus.service
+    if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
+        import dbus.glib
+        dbus_available = True
+        # optional : focus window in case of --newtab option, depend on wmctrl
+        import shlex, subprocess
+        subprocess_cmdline = "which wmctrl && wmctrl -i -a $(wmctrl -lpx |grep meld.Meld |awk '{print $1}')"
+    else:
+        # No dbus support 
+        pass
+except ImportError:
+    print "No dbus support."
+
+class DBusApp:
+    def register(self, app):
+        bus = dbus.SessionBus()
+        bus_name = dbus.service.BusName('net.sf.meld', bus=bus)
+        self.remote_instance = DBusProvider(bus_name, app)
+        
+    def running_already(self):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('org.freedesktop.DBus',
+                               '/org/freedesktop/DBus')
+        iface = dbus.Interface(proxy, 'org.freedesktop.DBus')
+        names = iface.ListNames()
+        if 'net.sf.meld' in names:
+            return True
+        return False        
+    
+    def remote_open_paths(self, args, auto_compare):
+        bus = dbus.SessionBus()
+        proxy = bus.get_object('net.sf.meld', '/net/sf/meld')
+        iface = dbus.Interface(proxy, 'net.sf.meld')
+        iface.open_paths(args, auto_compare)
+
+class DBusProvider(dbus.service.Object):
+    def __init__(self, bus_name, app, object_path='/net/sf/meld'):
+        dbus.service.Object.__init__(self, bus_name, object_path)
+        self.app = app
+        
+    @dbus.service.method('net.sf.meld')
+    def open_paths(self, args, auto_compare):
+        self.app.window.open_paths(args, auto_compare)        
 
 
 class FilterEntry(object):
@@ -164,6 +219,8 @@
             version="%prog " + version)
         parser.add_option("-L", "--label", action="append", default=[],
             help=_("Set label to use instead of file name"))
+        parser.add_option("-n", "--newtab", action="store_true", default=False,
+            help=_("Open a new tab in already running instance"))
         parser.add_option("-a", "--auto-compare", action="store_true", default=False,
             help=_("Automatically compare all differing files on startup"))
         parser.add_option("-u", "--unified", action="store_true",
@@ -185,7 +242,31 @@
                 parser.error(_("can't compare more than three directories"))
             self.window.open_paths(files)
 
+        # dbus handling
+        if options.newtab:
+            dbus_app = DBusApp()
+            running_already = False
+            # if successfull import dbus
+            if dbus_available:
+                # check any already registered instance
+                running_already = dbus_app.running_already()
+                if not running_already:
+                # dbus register it
+                    dbus_app.register(self)
+                else:
+                # use existing instance
+                    tab = dbus_app.remote_open_paths(args, options.auto_compare)
+                    # open new tab and exit
+                    self.parse_args_tab(tab, options)
+                    if subprocess_cmdline:
+                    # optional focus window subprocess
+                        subprocess.call(subprocess_cmdline, shell=True)
+                    sys.exit(0)
+            
         tab = self.window.open_paths(args, options.auto_compare)
+        self.parse_args_tab(tab, options)
+
+    def parse_args_tab(self, tab, options):
         if tab:
             tab.set_labels(options.label)
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]