2016-03-16 4 views
5

Was ich tun möchte, und warumWie unfocus (Blur) Python-gi GTK + 3 Fenster auf Linux

ich mein Fenster wollen unfocus, so dass die vorherigen fokussierten Fenster ausgewählt ist.

Warum? Ich möchte mit dem zuvor ausgewählten Fenster interagieren (aus anderen Programmen). Mein aktueller Plan ist: Unfocus mein Fenster, verwenden Sie libxdo, um Tastenanschläge zu simulieren, und fokussieren Sie dann mein Fenster erneut.

Mein Fenster kann oben angebracht werden, um zu vermeiden, dass Sie blättern. Sollte gut genug sein. Sieht einfach für mich aus. Aber ich kann es nicht zur Arbeit bringen.

Was ich versucht habe bisher

Ausblenden der Fenster mit Gtk.Widget.hide() und es dann wieder zeigt: Das Fenster zu viel flackert und es bewegte sich leicht einige Pixel nach oben (wegen der Window-Manager Hartnäckigkeit, ich annehmen).

Beispieltestcode

Aktuelle Code ruft Gtk.Window.set_focus(None), die nicht funktioniert. Ich muss diese Linie durch etwas anderes ersetzen, das macht, was ich will.

losefocus.py:

import signal 
from gi import require_version 
require_version('Gtk', '3.0') 
from gi.repository import GLib, Gtk, GObject 

class LoseFocusHandler: 
    def onClick(self, window): 
    print "Losing focus yet?" 
    window1 = builder.get_object("window1") 
    window1.set_focus(None) 

if __name__ == "__main__": 
    GObject.threads_init() 

    builder = Gtk.Builder() 
    builder.add_from_file("losefocus.glade") 
    builder.connect_signals(LoseFocusHandler()) 
    window1 = builder.get_object("window1") 
    window1.show_all() 

    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    Gtk.main() 

losefocus.glade:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- Generated with glade 3.16.1 --> 
<interface> 
    <requires lib="gtk+" version="3.10"/> 
    <object class="GtkWindow" id="window1"> 
    <property name="can_focus">False</property> 
    <property name="window_position">center-always</property> 
    <property name="gravity">center</property> 
    <child> 
     <object class="GtkButton" id="button1"> 
     <property name="label" translatable="yes">Lose Focus!</property> 
     <property name="visible">True</property> 
     <property name="can_focus">True</property> 
     <property name="receives_default">True</property> 
     <property name="relief">half</property> 
     <signal name="clicked" handler="onClick" swapped="no"/> 
     </object> 
    </child> 
    </object> 
</interface> 

Antwort

1

Eine einfache Lösung wäre, um aufzuzeichnen, welche Fenster vor Fokus hatte, sowohl wenn das Fenster erstellen und dann auf jedem focus-in-event und ausdrücklich darauf konzentrieren Fenster statt zu versuchen, das aktive zu unfokussieren:

import signal 
from gi import require_version 
require_version('Gtk', '3.0') 
from gi.repository import GLib, Gdk, Gtk, GObject 

class LoseFocusHandler: 
    def onClick(self, window): 
    print "Losing focus yet?" 
    old_window[0].focus(0) 

def focus_handler(gdk_window, event): 
    # At this point, our window does not have focus yet, but is 
    # about to. This hence works: 
    old_window[0] = gdk_window.get_screen().get_active_window() 

if __name__ == "__main__": 
    GObject.threads_init() 

    old_window = [ Gdk.Screen.get_default().get_active_window() ] 

    builder = Gtk.Builder() 
    builder.add_from_file("losefocus.glade") 
    builder.connect_signals(LoseFocusHandler()) 
    window1 = builder.get_object("window1") 
    window1.connect("focus-in-event", focus_handler) 
    window1.show_all() 

    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    Gtk.main() 
+0

Sehr schlau! Danke für den Tipp. Dies funktioniert jedoch zumindest mit Unity 7 nicht ordnungsgemäß. Das vorherige Fenster ist in der Taskleiste hervorgehoben, aber es ist überhaupt nicht fokussiert. –

+1

Unity verfügt über eine * Funktion zum Verhindern von Stehlen *, die von [compiz] geerbt wurde (https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/369954/comments/2), um Programme zu verhindern wenn Sie den Fokus ändern, aber stattdessen Programme in der Taskleiste markieren. Die 'focus()' Methode von GDKWindow [ruft den entsprechenden Xlib Befehl auf] (https://github.com/GNOME/gtk/blob/master/gdk/x11/gdkwindow-x11.c#L2250), und es funktioniert gut in Zimt. Ich habe Seiten gefunden, auf denen behauptet wird, dass Sie die Einstellung mithilfe von CCSM → Allgemeine Optionen → Fokus- und Raise-Verhalten anpassen können. – Phillip

+0

Leider brauche ich etwas, das auf Ubuntu out of the box funktioniert. Ich möchte Tastenanschläge an das andere Fenster senden. Da ich dank dir weiß, wie man die andere Fenster-ID bekommt, kann ich nun mit xdo den Fokus auf dieses Fenster legen, tippen und dann den Fokus wiederherstellen. Ich habe hier ein funktionierendes Beispiel gepostet: http://pastebin.com/0BsKYZtP Ich habe versucht, eine xdo-Funktion zu verwenden, um ein bestimmtes Fenster mit der Fenster-ID einzugeben, aber es scheint, dass 'XSendEvent' auch nicht funktioniert. Also aktiviere ich das Fenster separat, tippe dann ein und stelle den Fokus wieder her. So verlasse ich mich nur auf 'Xtest', das einwandfrei funktioniert. –

Verwandte Themen