Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 09/05/2011, à 21:58

Elzen

PyGTK – Pseudo-transparence et transmission des clics.

Kupo les gens,

Je bosse actuellement sur un projet de pseudo-environnement graphique baptisé Touhy (anciennement ElzDM, lien encore vaguement présent dans ma signature) (qui, si on regarde le code, ressemble à vrai dire plus à une énorme bidouille qu'à un véritable travaille digne de ce nom, mais passons), et il y a quelques points sur lesquels je bloque et pour lesquels j'aimerais bien quelques coups de main –ou au moins de la bonne doc, ce que je n'arrive désespérément pas à trouver.
Je squatte un peu le TdCCT à ce sujet depuis quelques temps, mais je me suis dit que (justement du fait de l'absence de résultat pertinents dans mes recherches), il pourrait être intéressant qu'il subsiste un sujet spécifique dédié à ces problèmes pour d'autres personnes qui auraient les mêmes soucis que moi.


Le premier point, c'est la pseudo-transparence. Mon Touhy, qui s'efforce d'être indépendant du gestionnaire de fenêtres, est donc conçu pour tourner sans qu'il n'y ait nécessairement de gestionnaire de composite actif, et d'autre part, le shape n'est pas toujours très pratique (en particulier pour afficher des icônes à transparence partielle) : je souhaiterais donc pouvoir utiliser la troisième solution. Mais je ne trouve pas comment intégrer ça dans une appli PyGTK.

J'utilise (intensivement) l'excellente bibliothèque wnck, qui permet pas mal de choses, notamment de brancher un écouteur pour être prévenu quand le fond d'écran de la fenêtre racine change, ce qui est déjà une bonne base. Le problème est qu'une fois averti que mon appli est censée se repeindre pour s'adapter au nouveau fond d'écran… reste le problème de récupérer ledit nouveau fond d'écran.
Je suppose que cette fonction-là est censée permettre cela, mais elle ne renvoie qu'un long dont je ne sais, en python, absolument pas quoi faire (le lien sus-cité porte sur la bibli en C, je n'ai même pas trouvé de doc' relative à son portage en python, c'est dire si j'ai perdu l'espoir de trouver des explications plus détaillées).
Le seul exemple semblant correspondre à peu près à ce que je veux sur lequel je sois tombé est celui-ci (dans la fonction get_mini_screenshot), mais ce n'est pas du python, et il semble utiliser le résultat comme un pointeur sur GdkPixmap, ce qui ne me semble pas transcriptible.

J'ai, à tout hasard, cherché du côté du code de l'ADeskBar (à qui j'ai déjà repompé ma gestion du systray), mais il semble, si j'ai bien regardé, que ce logiciel réalise sa propre « fausse transparence » à partir d'une capture d'écran, ce qui ne correspond pas à de la pseudo-transparence et me semble ne pas être adapté dans mon cas.
Quelqu'un verrait-il une autre approche ?


Point numéro deux, moins important mais dans le prolongement de cette idée : j'arrive à « repeindre » la fenêtre racine pour afficher un fond d'écran, mais cela semble être une décoration superficielle : l'écouteur sus-cité ne bronche pas, et les autres applications gérant déjà de la pseudo-transparence ne prennent pas cette action en compte.
Je propose donc, pour compenser, la possibilité d'appeler un programme externe (hsetroot ou feh, par exemple) pour appliquer le véritable changement, mais si d'aventure quelqu'un avait une piste permettant d'effectuer ça directement en interne, il pourrait être intéressant que mon appli en soit capable.

À titre indicatif, la méthode que j'utilise actuellement pour repeindre l'écran, en PyGTK simple :

#pixmap contient un gtk.gdk.Pixmap préalablement ajusté à la taille de l'écran
root = gtk.gdk.get_default_root_window()
root.set_back_pixmap(pixmap, False)
root.clear()

Tout simplement.


Troisième point, plus important celui-ci : je propose, entre autres, un gestionnaire de bureau, donc une fenêtre (de type « DESKTOP ») qui s'affiche à l'arrière-plan pour afficher des icônes. Cependant, une fenêtre ouverte « capture » les clics, qui ne sont donc pas transmis à la fenêtre racine. Or, certains gestionnaires de fenêtres (Openbox et Window Maker, notamment) réagissent aux clics sur la fenêtre racine, par exemple pour afficher un menu.
Je souhaiterais que mon appli n'empêche pas ces menus de s'ouvrir, et pour celà, j'aimerais donc trouver le moyen de « transmettre » le clic à la fenêtre racine. De rendre la fenêtre « transparence au clic », en quelque sorte. Il me semble que certains gestionnaires de bureau que je ne saurais pas nommer réagissent ainsi, et ça me paraît être le bon comportement.

Mais là encore, pas moyen de trouver comment faire, à moins d'utiliser du shape sur une partie de la fenêtre, ce qui serait assez peu pratique. J'ai tenté d'utiliser le module python-xlib pour simuler un clic sur la fenêtre racine, de la manière suivante :

import Xlib.display, Xlib.X, Xlib.protocol.event
display = Xlib.display.Display()
root = display.screen().root

def root_click(widget, event):
    root.send_event(Xlib.protocol.event.ButtonPress(
        detail=event.button, time=event.time, root=root,
            window=root, child=Xlib.X.NONE,
            root_x=event.x, root_y=event.y,
            event_x=event.y, event_y=event.x,
            state=0, same_screen=1), 0)
    display.sync()

root_click étant une fonction appelée au signal « button-press-event » sur mon gestionnaire de bureau, et cette fonction étant accompagnée d'une autre qui se déclenche au « button-release-event », et qui envoie un signal Xlib.protocol.event.ButtonRelease à la place de l'autre.
(Je me suis basé pour cela sur quelques semblants d'exemples trouvés à droite-à gauche, la bibliothèque python-xlib étant elle-même assez peu documentée).
Quelques essais effectués : cela semble vaguement en mesure de plus ou moins essayer de fonctionner sous Window Maker, mais pas la moindre réaction sous Openbox.
Est-ce que part hasard quelqu'un aurait une idée ?

Merci d'avance pour vos réponses.

Hors ligne

#2 Le 10/05/2011, à 07:47

Kanor

Re : PyGTK – Pseudo-transparence et transmission des clics.

Je  m'abonne

(sinon je me demande si ce serait pas mieux de passer par la librairie xcb
http://xcb.freedesktop.org/XcbPythonBinding/)

Dernière modification par Kanor (Le 10/05/2011, à 07:50)

Hors ligne

#3 Le 10/05/2011, à 18:22

Elzen

Re : PyGTK – Pseudo-transparence et transmission des clics.

Hmm, je ne connaissais pas ctte bibliothèque (library est un faux-ami, et d'ailleurs tu devrais mettre des balises url, parce que là, la parenthèse est prise dans le lien et le rend invalide wink)

Je tâcherai de jeter un œil de ce côté-là quand j'aurai le temps.

Hors ligne

#4 Le 01/06/2011, à 17:48

Elzen

Re : PyGTK – Pseudo-transparence et transmission des clics.

Bon, j'ai enfin du temps à consacrer à ce projet, j'me permets donc de upper ce sujet qui n'a pas l'air d'avoir inspiré grand monde yikes

J'ai essayé d'aller regarder la bibliothèque XCB, mais j'ai du mal à me repérer dans leur doc, donc dans l'immédiat, ça ne m'avance pas beaucoup hmm


Par contre, je viens de trouver pour la pseudo-transparence big_smile

En fait, il y avait juste une fonction que j'avais manqué dans gtk.gdk, qui permettait de récupérer un pixmap à partir d'un identifiant de ressource X.

Donc l'image se récupère comme ça :

screen = win.screen_get_default()
pixid = screen.get_background_pixmap()
if (pixid != 0):
    pixmap = gtk.gdk.pixmap_foreign_new(pixid)
    # Pour utiliser l'image comme fond d'une fenêtre, elle a besoin d'un colormap
    pixmap.set_colormap(gtk.gdk.colormap_get_system())

Ça ne résoud pas encore les autres points évoqués ci-dessus, mais ça en fait au moins un de bon ^^

Dernière modification par ArkSeth (Le 02/06/2011, à 00:59)

Hors ligne