2016-03-16 15 views
5

Quello che voglio fare e perchéCome unfocus (sfocatura) GTK 3 finestra Python-gi + su Linux

Voglio che la mia finestra per unfocus, quindi viene selezionata la finestra in primo piano precedente.

Perché? Voglio interagire con la finestra precedentemente selezionata (da altri programmi). Il mio piano attuale è: sfoca la finestra, usa libxdo per simulare i tasti, quindi concentra nuovamente la finestra.

La mia finestra può essere impostata sulla parte superiore per evitare di sfogliare. Dovrebbe essere abbastanza buono Sembra semplice per me. Ma non riesco a farlo funzionare.

Quello che ho provato finora

nascondere la finestra con Gtk.Widget.hide() e poi mostrando di nuovo: la finestra lampeggia troppo ed è leggermente spostato alcuni pixel verso l'alto (a causa del window manager testardaggine, mi supponiamo).

prova Esempio codice

codice attuale chiama Gtk.Window.set_focus(None) che non funziona. Devo sostituire quella linea con qualcos'altro che rende ciò che voglio che faccia.

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> 

risposta

1

Una soluzione semplice sarebbe quella di registrare quale finestra aveva messa a fuoco prima, sia durante la creazione della finestra e poi su ogni focus-in-event, ed esplicitamente messa a fuoco che finestra invece di cercare di sfocare l'attivo:

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

Molto intelligente! Grazie per il consiglio. Tuttavia, questo non funziona correttamente, almeno con Unity 7. La finestra precedente è evidenziata nella barra delle applicazioni ma non è affatto focalizzata. –

+1

Unity dispone di una funzione di prevenzione del furto * * che è stata ereditata da [compiz] (https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/369954/comments/2), progettata per impedire i programmi dal cambiare focus ma evidenziando i programmi nella barra delle applicazioni. Un metodo 'focus()' di GDKWindow [richiama il comando Xlib appropriato] (https://github.com/GNOME/gtk/blob/master/gdk/x11/gdkwindow-x11.c#L2250), e funziona perfettamente Cannella. Ho trovato pagine che affermano che è possibile regolare le impostazioni usando CCSM → Opzioni generali → Focus & Raise Behavior. – Phillip

+0

Purtroppo, ho bisogno di qualcosa che funzioni fuori dalla scatola su Ubuntu. Voglio inviare sequenze di tasti all'altra finestra. Dal momento che so grazie a te come ottenere l'altro ID della finestra, ora posso usare xdo per concentrarmi su quella finestra, digitare e quindi ripristinare lo stato attivo. Ho pubblicato un esempio di lavoro qui: http://pastebin.com/0BsKYZtP Ho provato a utilizzare una funzionalità xdo per digitare una determinata finestra utilizzando l'ID della finestra, ma sembra che 'XSendEvent' non funzioni. Quindi attendo separatamente la finestra, quindi digitando, quindi ripristinando la messa a fuoco. In questo modo mi baso solo su 'Xtest' che sembra funzionare in modo impeccabile. –

Problemi correlati