2016-03-16 14 views
5

Co chcę zrobić i dlaczegoJak unfocus (blur) Python-Gi GTK + 3 okna na Linuksie

Chcę moje okno na unfocus, więc wybrano poprzedni skupiony okno.

Dlaczego? Chcę wejść w interakcję z wcześniej wybranym oknem (z innych programów). Mój obecny plan to: unfocus my window, użyj libxdo, aby symulować naciśnięcia klawiszy, a następnie ponownie ustaw moje okno.

Moje okno można ustawić na górze, aby uniknąć drgania. Powinien być wystarczająco dobry. Wygląda prosto na mnie. Ale nie mogę zmusić go do działania.

Co Próbowałem tak daleko

Ukrywanie okna z Gtk.Widget.hide() a następnie pokazano ją ponownie: Okno migocze zbyt dużo i jest lekko przesunięte o kilka pikseli w górę (ze względu na Window Manager upór, ja przypuszczać).

Test przykładowy kod

Aktualny kod wywołuje Gtk.Window.set_focus(None), który nie działa. Muszę zastąpić tę linię czymś, co robi to, co chcę.

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> 

Odpowiedz

1

Prostym rozwiązaniem byłoby nagrać które okno miał skupić się wcześniej, zarówno podczas tworzenia okna, a następnie na każdym focus-in-event i wyraźnie koncentrują że zamiast zamykać nieaktywne okno:

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

Bardzo sprytny! Dzięki za wskazówkę. Jednak to nie działa poprawnie, przynajmniej z Unity 7. Poprzednie okno jest podświetlone na pasku zadań, ale nie jest w ogóle skupione. –

+1

Unity ma * funkcję zapobiegania kradzieży * skupienia, którą odziedziczyła po [compiz] (https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/369954/comments/2), zaprojektowaną w celu zapobiegania programom zamiast zmieniać ostrość, ale zamiast tego podświetlać programy na pasku zadań. Metoda 'focus()' GDKWindow [wywołuje odpowiednie polecenie Xlib] (https://github.com/GNOME/gtk/blob/master/gdk/x11/gdkwindow-x11.c#L2250) i działa dobrze w Cynamon. Znalazłem strony, które twierdzą, że możesz dostosować ustawienie za pomocą CCSM → Opcje ogólne → Ustaw ostrość i podbicie. – Phillip

+0

Niestety, potrzebuję czegoś, co działa po wyjęciu z pudełka na Ubuntu. Chcę wysłać naciśnięcia klawiszy do drugiego okna. Ponieważ wiem, dzięki tobie, jak uzyskać inny identyfikator okna, mogę teraz użyć xdo, aby uzyskać skupienie na tym oknie, wpisać i przywrócić fokus. Wysłałem przykład pracy tutaj: http://pastebin.com/0BsKYZtP Próbowałem użyć funkcji xdo do wpisania do określonego okna przy użyciu identyfikatora okna, ale wygląda na to, że 'XSendEvent' też nie działa. Dlatego osobno aktywuję okno, następnie wpisuję, a następnie przywracam fokus. W ten sposób polegam tylko na "Xtest", który wydaje się działać bezbłędnie. –