Contenu | Rechercher | Menus

Annonce

Ubuntu 16.04 LTS
Commandez vos DVD et clés USB Ubuntu-fr !

Pour en savoir un peu plus sur l'équipe du forum.

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.

#101 Le 17/03/2017, à 16:58

grim7reaper

Re : /* Topic des codeurs [9] */

@Dafyd: Yep, Haskell c’est bien sympa comme langage fonctionnel. Tu peux partir là-dessus si tu veux smile

Hors ligne

#102 Le 29/06/2017, à 21:10

Elzen

Re : /* Topic des codeurs [9] */

Bon, je suis en train de tenter de migrer Touhy à GTK3 (pour enfin pouvoir faire du Python3), mais il y a un paquet de trucs qui ne s'annoncent pas évidents hmm

Par exemple, pour faire ma barre d'onglets en haut de l'écran. Évidemment, un widget qui présente seulement cette barre d'onglets, indépendante du Notebook, ça n'existe toujours pas (il me semble que ça existe en Qt). Donc, comme pour la version GTK2, je tente de « tricher » en mettant un Notebook et en en cachant la partie du bas. Sauf que j'ai eu beau essayer tous les moyens de régler la taille de la fenêtre que j'ai pu trouver, pas moyen de réduire la fenêtre à la bonne hauteur. Même en mettant le Notebook dans un Viewport, qui est censé être fait pour ça, ça continue d'agrandir la fenêtre pour me l'afficher en entier yikes
Donc, j'ai tenté de me rabattre sur l'autre option: laisser la fenêtre prendre trop de place, et utiliser du shape (l'extension de X11 pour faire des trous dans les fenêtres même sans composite) pour n'afficher que la partie utile. Sauf que, là encore: la fonction shape_combine_mask de GTK2, qui prenait un Pixmap facile à obtenir comme argument, a été remplacée par shape_combine_region, qui prend désormais un objet conçu sur mesure. Pour générer cet objet région, deux fonctions existent en GDK : create_from_pixbuf qui n'a pas l'air disponible en Python, et create_from_surface… qui cause une segfault.
J'ai tenté de créer l'objet Region en attaquant cairo directement, mais sans succès pour le moment. Le seul espoir que je vois de réussir à faire ça, là, c'est d'attaquer la Xlib directement, si seulement c'est faisable…

Franchement, si quelqu'un a un tuyau, je prends hmm

En ligne

#103 Le 03/07/2017, à 14:15

grim7reaper

Re : /* Topic des codeurs [9] */

Si je comprends bien ce que tu veux faire, tu veux voir seulement [page 1][page 2][page 3] sur cet exemple?
Est-ce que tu dois vraiment passer par un Notebook?
Je connais pas les détails mais tu pourrais pas simplement avoir une fenêtre avec des boutons/whatever empilé horizontalement?

Hors ligne

#104 Le 03/07/2017, à 22:18

Elzen

Re : /* Topic des codeurs [9] */

Bah, techniquement, implémenter ça avec des boutons ou n'importe quel autre truc cliquable simple d'utilisation serait beaucoup plus facile, oui; mais le principe du truc est de simuler une barre d'onglets pour gérer le multibureaux (un onglet = un espace de travail). Or, à moins de trouver comment intégrer une feuille de style spécifique pour ce truc-là (auquel cas ça aura toutes les chances de ne pas coller avec le thème sur une autre machine que la mienne), faire autrement ne rendrait pas du tout la tronche des onglets et donc casserait un peu le truc.

Pour vous donner une idée, la version GTK2 ressemble à ça:
1499116623.png

(Après vérification, il y a bien une barre d'onglets standalone dans Qt, un truc comme ça en GTK me simplifierait considérablement la vie)

En ligne

#105 Le 06/07/2017, à 07:12

grim7reaper

Re : /* Topic des codeurs [9] */

Hum, en effet mis à part le Notebook je ne vois pas comment faire ça en GTK hmm, c’est dommage de pas avoir un widget pour ça.
Au lieu de migrer GTK 2 -> GTK 3, mieux vaut peut-être migrer GTK 2 -> Qt ^^

Hors ligne

#106 Le 06/07/2017, à 10:41

Elzen

Re : /* Topic des codeurs [9] */

C'est ce que je comptais faire à une époque, mais le pas à franchir entre les deux m'a pas mal refroidi (je ne sais plus les détails, mais il me semble que Qt a une logique inversée par rapport à tout ce que je connais d'autre comme bibliothèques graphiques, du genre passer les conteneurs aux contenus et pas l'inverse, par exemple).
Puis, en regardant dans les détails, GTK3 apporte quelques trucs assez sympa et agréables à utiliser, et y a quelques améliorations logiques au niveau du code (même s'il y a aussi pas mal de trucs sympas qui disparaissent et que le pseudo-CSS pour le style est juste une énorme régression), donc maintenant que je commence à me débrouiller avec la bête, j'aurais bien aimer continuer…

En GTK2, j'avais réussi à me faire un widget «barre d'onglet» sans trop de difficultés en mettant un Notebook dans un Viewport, et ça pouvait marcher dans toutes les directions facilement; mais là, vu que le viewport n'est pas foutu de viewporter, ça va être plus dur. Si j'arrivais juste à faire marcher le shape, ça pourrait aller pour cet outil-là, au moins, mais dans l'immédiat, à part taper dans la Xlib, ce dont j'ai moyennement envie, je ne vois pas.

(Un jour, j'me coderai ma propre bibliothèque graphique, ce sera plus simple ><)

En ligne

#107 Le 06/07/2017, à 22:34

HP

Re : /* Topic des codeurs [9] */

The Safe Navigation Operator (&.) in Ruby

http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

if account && account.owner && account.owner.address

end
account&.owner&.address

Petite trouvaille du soir… en utilisant l'excellent RuboCop qui m'a gratifié du message suivant :

lib/ylem/helper/subprocess.rb:44:33: C: Style/SafeNavigation: Use safe navigation (&.) instead of checking if an object exists before calling the method.
        .map { |source, thread| thread.join if thread }

cat /dev/urandom >/dev/null 2>&1 #621141 - Pi

Hors ligne

#108 Le 07/07/2017, à 11:06

cervo

Re : /* Topic des codeurs [9] */

HP a écrit :

The Safe Navigation Operator (&.) in Ruby

http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/

à utiliser sans modération

Hors ligne

#109 Le 10/07/2017, à 14:22

Elzen

Re : /* Topic des codeurs [9] */

Tiens, en attendant des pistes de résolutions du problème sus-mentionné, un autre truc qui me trotte dans la tête.

Sur mon blog, actuellement, il y a une version http pas sécurisé accessible à tout le monde, et une version https qui demande un login/mdp (m'enfin, mettre guest:guest, ça passe). Je fais ça par une authentification http directement, la plus grande partie du site étant statique et rajouter une couche de cgi juste pour ça me plaisant moyen.
J'aimerais bien mettre en place un accès https qui ne nécessite pas d'entrer de login/mdp, histoire que n'importe qui puisse naviguer sur mon site de façon chiffrée sans se faire prendre la tête par une popup dès l'ouverture (même que ça pourrait être une raison qui me motiverait à passer à let's encrypt plutôt que de rester autosigné). Pour autant, il y a des trucs pour lesquels je veux garder un accès restreint, et perso, j'aime bien que le mot de passe soit demandé une fois pour toute à l'affichage de la première page, même si elle n'a rien qui nécessite une sécurisation, plutôt que de tomber dessus comme ça en cours de navigation.

Du coup, je me demande: est-il, à votre connaissance, possible de configurer le serveur web pour que:
– Si tu insistes pour te loguer (genre en précisant login@ dans l'URL de la première page que tu affiches), tu es logué une bonne fois pour toutes, et les informations resteront transmises pendant toute ta navigation,
– Si non, ça te laisse juste naviguer normalement, comme s'il n'y avait pas d'authentification?

Edit: configurer le serveur web, attendu que je suppose que c'est le serveur qui redemande au navigateur les infos de login à chaque tentative de connexion, et pas le navigateur qui les envoie tout seul, dans le doute, en continuant même si ça ne sert à rien… mais je n'ai jamais testé, en fait yikes Si quelqu'un a de la bonne doc' sur la façon dont est gérée l'authentification http des deux côté, ça m'intéresse.

Dernière modification par Elzen (Le 10/07/2017, à 14:31)

En ligne

#110 Le 12/07/2017, à 12:33

grim7reaper

Re : /* Topic des codeurs [9] */

Elzen a écrit :

Si quelqu'un a de la bonne doc' sur la façon dont est gérée l'authentification http des deux côté, ça m'intéresse.

À priori, ce que tu utilises c’est le Digest access authentication de HTTP, du coup Wikipédia est un bon point de départ.

L’outil Network de Firefox (dans la section Developer  chez moi) permet aussi de se faire une idée de ce qui se passe en regardant les requêtes HTTP qui passent.
De ce que j’ai vu après un rapide test:
- accès en HTTP: RAS.
- accès en HTTPS:
* Le navigateur faire un GET
* Ton serveur répond 401 avec l’en-tête WWW-Authenticate:"Digest realm="", nonce="4b179c56e2ae416d86acf85bbe2b691d", qop="auth""
* Mon navigateur renvoie la requête GET avec l’en tête Authenticate qui va bien
* Ton serveur répond 200
* Je clique sur un lien pour aller sur une autre page (toujours en HTTPS) => mon navigateur renvoie l’en tête Authenticate (sans me redemander mon login/mot de passe, il doit guarder ça en cache…)
* Ton serveur me répond 200 (vu que je continue d’envoyer l’en-tête)

Si j’édite la requête HTTP pour enlever l’en-tête ou vide le cache qui contient mes identifiants, ton serveur va me rebalancer un 401 pour me demander de me loguer (parce que je n'envoie plus l’en-tête).
Donc à priori, c'est renvoyé pour chaque page (ce qui ne semble pas surprenant au final : HTTP étant un protocole stateless il ne peux pas se souvenir si tu es loggué ou pas).

Dernière modification par grim7reaper (Le 12/07/2017, à 12:35)

Hors ligne

#111 Le 12/07/2017, à 13:05

Elzen

Re : /* Topic des codeurs [9] */

Ça n'a rien de surprenant, en effet; mais je pensais naïvement que le navigateur attendait de recevoir la demande d'authentification de la part du serveur pour renvoyer les infos (ce qui n'aurait pas nécessité de session non plus, le serveur envoyant la demande systématiquement tant qu'il ne reçoit pas ce dont il a besoin).

Du coup, la question serait de tenter de mettre l'en-tête qui va bien sans pour autant renvoyer la 401, et de regarder ce qui se passe dans ce cas-là; mais la problématique a l'air de se situer principalement du côté du navigateur.

Merci pour le lien, je vais détailler ça.


(Sinon, pour l'autre problème, j'ai trouvé une parade temporaire, faute de mieux: une GtkSocket dans le panel en GTK3, et la barre d'onglets dans un GtkPlug géré par du code PyGTK. Pas forcément ce qu'il y a de plus léger, mais d'un autre côté, ça permet une certaine souplesse)

En ligne

#112 Le 13/07/2017, à 09:57

grim7reaper

Re : /* Topic des codeurs [9] */

Elzen a écrit :

Ça n'a rien de surprenant, en effet; mais je pensais naïvement que le navigateur attendait de recevoir la demande d'authentification de la part du serveur pour renvoyer les infos (ce qui n'aurait pas nécessité de session non plus, le serveur envoyant la demande systématiquement tant qu'il ne reçoit pas ce dont il a besoin).

En effet, ça aurait été une solution possible mais du coup ça demande 2 requêtes par page (un GET qui se prend un 401, puis un GET avec les informations), c’est peut-être pour ça que ça n’a pas été retenu.

Elzen a écrit :

(Sinon, pour l'autre problème, j'ai trouvé une parade temporaire, faute de mieux: une GtkSocket dans le panel en GTK3, et la barre d'onglets dans un GtkPlug géré par du code PyGTK. Pas forcément ce qu'il y a de plus léger, mais d'un autre côté, ça permet une certaine souplesse)

Tu peux détailler?
Je connaissais pas ce système de GtkSocket/GtkPlug.

Hors ligne

#113 Le 13/07/2017, à 12:47

Elzen

Re : /* Topic des codeurs [9] */

grim7reaper a écrit :

En effet, ça aurait été une solution possible mais du coup ça demande 2 requêtes par page (un GET qui se prend un 401, puis un GET avec les informations), c’est peut-être pour ça que ça n’a pas été retenu.

Yep, en effet.

Mais du coup, j'imagine que pour des sites pour lesquels la demande d'authentification ne concerne qu'une petite partie de l'arborescence, le navigateur continue d'envoyer les infos de connexion à chaque fois alors que c'est inutile, ce qui n'est pas forcément glop non plus. Il faudra que je regarde ce que le serveur en fait dans ces cas-là. J'me demande aussi comment le navigateur réagit quand il se mange une 401 sur une requête AJAX, demande-t-il l'authentification comme ça, alors que le reste de la page est déjà chargée? Bref, quand je serai en situation de pouvoir bosser correctement, je ferai quelques tests et j'aviserai en fonction.

grim7reaper a écrit :

Tu peux détailler?
Je connaissais pas ce système de GtkSocket/GtkPlug.

Dans l'usage de base, c'est relativement simple; après, naturellement, je m'en sers bizarrement big_smile

Un gtk.Plug est un widget top level, comme une fenêtre, mais qui n'est pas conçu pour être affiché directement. Il doit être embarqué dans un autre (ça passe par un protocole X dédié, Xembed). Le gtk.Socket est le widget conteneur associé. Un des objectifs est de permettre de gérer une partie du contenu d'une fenêtre depuis un autre processus, et ça peut aussi servir à croiser les bibliothèques graphiques. Je subodore que ce soit ce qui est utilisé pour les dockapps de Window Maker, par exemple; ou pour la prévisualisation des thèmes GTK dans lxappearance.

Dans mon cas, je configure mon panel (GTK3) en indiquant les noms des éléments à utiliser, et si un des noms proposés ne correspond à rien, je place une Socket, et je publie sur un presse-papier dédié (j'aime bien utiliser des presses-papiers dédiés, c'est un des moyens de communication entre applis les plus simples à utiliser, à mon sens) le nom du widget et l'Xid de la Socket. Comme ça, mon appli en GTK2 n'a plus qu'à consulter le presse-papier en question, remarquer qu'on lui demande la barre de menu, et la créer dans le Plug qui ira s'insérer dans la Socket en question. Ça permettra aussi d'enrichir le panel depuis d'autres applis en cas de besoin.

En ligne

#114 Le 13/07/2017, à 13:53

grim7reaper

Re : /* Topic des codeurs [9] */

Merci pour les détails.

Hors ligne

#115 Le 14/08/2017, à 02:10

Elzen

Re : /* Topic des codeurs [9] */

grim7reaper a écrit :

Si je comprends bien ce que tu veux faire, tu veux voir seulement [page 1][page 2][page 3] sur cet exemple?
Est-ce que tu dois vraiment passer par un Notebook?
Je connais pas les détails mais tu pourrais pas simplement avoir une fenêtre avec des boutons/whatever empilé horizontalement?

J'ai réussi \o/

Il a fallu pas mal de temps pour trouver, mais j'ai enfin réussi à tracer des onglets tous seuls, sans le gtk.Notebook autour.

Il « suffit » d'utiliser les méthodes gtk_render_* avec l'objet StyleContext qui va bien pour le widget désiré (en l'occurrence, il faut utiliser gtk_render_background et gtk_render_frame. Quoique les onglets soient explicitement mentionnés dans la description de gtk_render_extension, en fait, cette méthode fait la même chose que les précédentes, mais en virant la bordure sur un côté, ce qui est pratique dans certains cas mais ne sert pas ici).
Le souci, c'est que j'ai eu beau essayer plein de manières différentes d'obtenir un StyleContext à partir d'un Widget GTK (méthode get_style_context(), en essayant de recréer l'arborescence sur les objets), ce qui se dessinait ne ressemblait jamais à un onglet. Et en fait, je viens de réussir ce soir en créant le StyleContext entièrement à la main pour y mettre les informations que je veux.

Du coup, ça donne un truc comme ça:

style = gtk.StyleContext()
if active:  # Styler comme l'onglet actif.
    style.set_state(gtk.StateFlags.CHECKED)
wpath = gtk.WidgetPath()
for i, name in enumerate(["notebook", "header", "tabs", "tab"]):
    wpath.append_type(gtk.Notebook)  # Sans un append_ avant le iter_set_, ça segfault.
    wpath.iter_set_object_name(i, name)
wpath.iter_add_class(1, edge)  # "top", "left", "right" ou "bottom"
style.set_path(wpath)

Et ensuite, on peut tranquillement peindre ça, et ça a bien la tête demandée.

Il suffit donc ensuite de peindre ça sur le fond des différents widgets censés ressembler à des onglets, et tout marche.
Il faut encore que je joue un peu avec pour être sûr, mais je crois bien que ce truc est réglé smile


(Sinon, pour le shape, en fait c'est en fait très simple à faire, maintenant :

window.shape_combine_region(cairo.Region([cairo.RectangleInt(x1, y1, w1, h1), cairo.RectangleInt(x2, y2, w2, h2), …])

mais bon, du coup je n'en ai plus besoin pour ça, donc ça va.)


Par contre, évidemment, ce n'est pas comme si j'avais tout réglé non plus.
Par exemple, pour gérer le bureau, j'aimerais bien pouvoir afficher l'image d'arrière plan X simplement. En GTK2, ça se faisait comme ça:

wid = wnck.screen_get_default().get_background_pixmap()
if wid > 0L:
    display = gtk.gdk.display_get_default()
    pixmap = gtk.gdk.pixmap_foreign_new_for_display(display, wid)
    pixmap.set_colormap(gtk.gdk.screen_get_default().get_rgb_colormap())
    # S'il y a besoin de convertir le pixmap en pixbuf…
    w, h = pixmap.get_size()
    pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
    pixbuf.get_from_drawable(pixmap, gtk.gdk.colormap_get_system(), 0, 0, 0, 0, w, h)

La fonction get_background_pixmap() existe encore dans WNCK, donc j'arrive encore à accéder à l'id de la fenêtre X correspondante, mais c'est ensuite que ça se gâte :
– gdk.pixmap_foreign_new_for_display n'existe plus en GTK3, puisque les GdkPixmap ont été entièrement dégagés au profit des CairoSurface (ce qui n'est pas forcément plus mal, d'ailleurs).
– Il existe normalement une fonction cairo_xlib_surface_create_for_bitmap qui devrait avoir le même effet, mais après recherche, elle n'a présentement pas de binding python (apparemment, parce qu'ils ne connaissent pas python-xlib).
– Il y a bien un GdkX11.X11Window.foreign_new_for_display, mais il ne marche pas pour récupérer ça, apparemment (ça permet par contre d'accéder aux vraies fenêtres, il y avait une fonction équivalente en GTK2 aussi).

Du coup, en attendant, je lance une appli en PyGTK en arrière-plan qui récupère cette image et me la colle dans un presse-papier, histoire de pouvoir ensuite la récupérer dans GTK3 quand même, ce qui n'est pas franchement la solution idéale.
Si quelqu'un a une piste pour ce dernier problème, je prends smile

En ligne

#116 Le 18/08/2017, à 17:56

Elzen

Re : /* Topic des codeurs [9] */

Bon, double post, parce que :

Elzen a écrit :

J'ai réussi \o/

[…]

Il suffit donc ensuite de peindre ça sur le fond des différents widgets censés ressembler à des onglets, et tout marche.
Il faut encore que je joue un peu avec pour être sûr, mais je crois bien que ce truc est réglé smile

Eut-ce été si simple que ça que ça n'aurait pas été drôle roll

Le moyen décrit ci-dessus marche très bien pour tracer un onglet, prit isolément de tout le reste. Le truc est que les onglets sont rarement isolés, et que parfois, les thèmes ont des petites subtilités quand ils se suivent. Du genre, virer la bordure de gauche des onglets qui ne sont pas en première position pour éviter que ça fasse trop large. Donc il y a des trucs à rajouter dans mon code.

La section « description » du GtkWidgetPath dans la doc parle encore d'utiliser des GtkRegionFlags pour ce genre de trucs, mais ils sont dépréciés depuis un bout de temps (et n'ont pas donné grand chose quand j'ai testé). Donc je suppose qu'il faut plutôt passer par append_with_siblings, mais je ne pige rien à la façon de s'en servir.

Tenez, plutôt que de longues explications, je pense qu'une simple capture sera assez claire sur le problème :
1503075122.png
(Notez que, ça n'apparaît pas sur la légende, mais dans la CSS utilisée pour cet exemple, j'ai aussi le fait que le sélecteur « tab+tab » double la largeur de la bordure, ce qui ne marche nulle part ici).

Si quelqu'un capte quelque chose à la façon d'utiliser append_with_siblings, tout coup de main sera le bienvenu (jusque là, je n'ai trouvé d'exemple d'utilisation nulle part, seulement divers clones de la page de doc' sus-liée qui n'est pas très détaillée à ce sujet)

Ceci dit, au passage, vous pouvez quand même remarquer, en haut de l'écran, ma barre d'onglets des bureaux version GTK3 in situ, en lieu et place de celle en GTK2 sur la capture précédente smile

En ligne