#1 Le 20/02/2020, à 09:41
- LukePerp
[Résolu] Hook position souris
Bonjour,
je voudrais savoir quelle commande permet de placer un hook sur les coordonnées de la position de la souris ? Je voudrais intercepter les mouvements de la souris lorsqu'elle touche le bord supérieur de l'écran, c'est à dire quand Y=0. Je connais les commandes xdotool et xinput qui permettent en autre de déterminer les coordonnées X, Y de la position de la souris mais ces commandes ne permettent pas de faire un Hook. Je sais les utiliser avec une boucle while do pour intercepter les coordonnées qui m'intéressent mais la boucle consomme beaucoup le processeur, ce qui un défaut majeur pour moi. Je connais la commande xbindkeys qui permet entre autre de faire un hook sur les clics de la souris mais ne gère pas les coordonnées de la souris. Quelle commande permettrait de faire un hook sur les coordonnées de la position de la souris, comme xbindkeys le fait pour les clics ?
Dernière modification par LukePerp (Le 21/03/2020, à 21:00)
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne
#2 Le 07/03/2020, à 17:42
- LeoMajor
Re : [Résolu] Hook position souris
bonjour,
dépend du contexte
si c'est une application existante, il faut faire un service systemd, en espérant qu'il n' y a pas d'effets secondaires avec les évènements de l'application existante. Cela revient à faire un travail de macro.
si c'est une application que tu crées, et bien cela dépend du langage & framework utilisés. Les contrôles graphiques sont vus comme des variables objets avec leurs propriétes, méthodes, évènements (relatifs à X).
exemple en gambas,
Fmain ou Form1; fenêtre principale de l'application
Public tts As New TextBox[]
Public ttn As New TextBox(FMain)
Public Sub init()
Dim i As Integer
FMain.Tracking = True
FMain.FullScreen = True
For i = 1 To 3
ttn = New TextBox(Fmain) As "alltextboxes"
tts.Add(ttn)
With ttn
.Name = "T" & Str(i)
.H = 32
.W = 150
.Y = 40 * i
.X = 10
End With
Next
End
Public Sub testa()
Dim item As TextBox
For Each item In tts
Print item.Name, item.Parent.Name, item.X, item.Y, item.Enabled, item.Visible
Next
End
Public Sub Form_Open()
init()
testa()
End
Public Sub Form_MouseMove()
Dim dk As Desktop, mo As Mouse
tts[0].text = "X: " & mo.X & " dkx: " & dk.W
tts[1].text = "Y: " & mo.Y & " dky: " & dk.H
If mo.X = 0 Then Message("la souris est sur le bord gauche")
End
Public Sub Form_MouseDown()
Dim mo As Mouse
tts[2].text = "Button: " & mo.Button
End
Public Sub alltextboxes_Enter()
Dim focus As Textbox
focus = Last
focus.Text = "Enter"
End
Hors ligne
#3 Le 08/03/2020, à 10:27
- LukePerp
Re : [Résolu] Hook position souris
A l'origine, je recherchais une solution en bash, mais autant pour moi, je n'avais pas préciser. Ta solution en gambas me plaît bien, j'ai joué avec et je reconnais que c'est bien un hook et non une boucle. En revanche, tel quel, ce hook ne fonctionne que sur l'affichage de cette fenêtre FMain. Fenêtre réduite ou cachée, ça ne fonctionne plus. Comment faire la même chose en global en cachant la fenêtre ?
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne
#4 Le 15/03/2020, à 23:12
- LeoMajor
Re : [Résolu] Hook position souris
c'est normal. tu perds le focus. Chaque application gère son interface.
tu crées un fichier classe genre "MouseIO",
qui tantôt va se comporter comme objet natif gambas mouse ,
tantôt comme une macro
' Gambas class file
''Mouse mode macro (suite à la perte du focus sur une autre application)
Export
Property Name As String
Property Read X As Integer
Property Read Y As Integer
Property Read Native As Boolean
Event MouseMove(X As Integer, Y As Integer, Native As Boolean)
'' Native GambasObject mo as Mouse
'' NotNative /usr/bin/xmousepos xautomation
Private fname As String
Static Private fnative As Boolean = True
Private ti As New Timer As "eti"
Private Function X_Read() As Integer
Dim mo As Mouse, p As String, pp As String[]
fnative = True
Try Return mo.X
If Error Then
Exec ["/usr/bin/xmousepos"] To p
pp = Split(p, " ")
fnative = False
Return CInt(pp[0])
End If
End
Private Function Y_Read() As Integer
Dim mo As Mouse, p As String, pp As String[]
fnative = True
Try Return mo.Y
If Error Then
Exec ["/usr/bin/xmousepos"] To p
pp = Split(p, " ")
fnative = False
Return CInt(pp[1])
End If
End
Private Function Name_Read() As String
Return fname
End
Private Sub Name_Write(Value As String)
fname = Value
End
Private Function Native_Read() As Boolean
Return fnative
End
Public Sub GetMouse()
Dim mo As Mouse, p As String, pp As String[], a As Integer, b As Integer
fnative = True
Try a = mo.X And b = mo.Y
If Error Then
Exec ["/usr/bin/xmousepos"] To p
pp = Split(p, " ")
fnative = False
a = CInt(pp[0])
b = CInt(pp[1])
Endif
Raise MouseMove(a, b, fnative)
End
Public Sub eti_Timer()
GetMouse()
End
Public Sub Start()
ti.delay = 40
ti.Start
End
Public Sub Stop()
ti.Stop()
End
dans ta fenêtre principale genre Fmain, Form1, selon l'exemple précédent
Public tt As New MouseIO As "ett"
...
Public Sub init()
..
tt.Name = "MMouse"
...
Public Sub Form_MouseMove()
Dim dk As Desktop, mo As Mouse
tts[0].text = "X: " & mo.X & " " & tt.X & " " & tt.Native
tts[1].text = "Y: " & mo.Y & " " & tt.Y & " " & tt.Native
End
Public Sub ett_MouseMove(X As Integer, Y As Integer, Natif As Boolean)
Print X, Y, Natif
End
Public Sub Form_Leave()
tt.Start()
End
Public Sub Form_Enter()
tt.Stop()
End
Hors ligne
#5 Le 18/03/2020, à 07:18
- LukePerp
Re : [Résolu] Hook position souris
J'ai vite fais essayé. Je reviendrai commenter
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne
#6 Le 18/03/2020, à 07:56
- moko138
Re : [Résolu] Hook position souris
Pardon, mais qu'est-ce que c'est,
un hook sur les coordonnées de la position de la souris
?
Je suppose que ce n'est pas un pointeur, parce que vous auriez employé ce mot.
Alors est-ce, sur les bords de la fenêtre, l'affichage en clair des coordonnées, comme le fait Gimp ?
%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel : À la découverte de dcraw
Hors ligne
#7 Le 18/03/2020, à 09:36
- LukePerp
Re : [Résolu] Hook position souris
Pardon, mais qu'est-ce que c'est,
un hook sur les coordonnées de la position de la souris
?
Je suppose que ce n'est pas un pointeur, parce que vous auriez employé ce mot.Alors est-ce, sur les bords de la fenêtre, l'affichage en clair des coordonnées, comme le fait Gimp ?
Définition
Le Hook est un « hameçon » posé par une application dans le flux de messages système d'un certain type. Il permet à cette application de « capturer » ces messages et d'y réagir.
Fonctionnement
Techniquement, il s'agit de positionner une procédure de traitement dans une chaîne de traitement de messages d'un type donné.
Il faut pour cela :
choisir le positionnement du Hook :
- Hook Local : capture des messages dans le flux d'un thread (celui de l'application ou un autre),
- Hook Global : capture des messages dans le flux système ;
choisir le type de messages devant être capturés ;
positionner le Hook au sein de la chaîne de traitement de ces messages ;
traiter les messages par une procédure dédiée ;
mettre à disposition les messages pour les autres Hooks de la chaîne ;
lorsque le Hook devient inutile, le retirer de la chaîne.
Source : developpez.com
Dernière modification par LukePerp (Le 18/03/2020, à 20:06)
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne
#8 Le 18/03/2020, à 09:57
- moko138
Re : [Résolu] Hook position souris
Merci !
Euh... Le "fonctionnement" ressemble à une description faite par ceux qui savent déjà, à l'intention de ceux qui savent déjà.
Mais de la définition, je crois comprendre que tu veux extraire les coordonnées de la souris pour t'en resservir sans idée d'affichage graphique : est-ce correct ?
%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel : À la découverte de dcraw
Hors ligne
#9 Le 18/03/2020, à 20:04
- LukePerp
Re : [Résolu] Hook position souris
je crois comprendre que tu veux extraire les coordonnées de la souris pour t'en resservir sans idée d'affichage graphique : est-ce correct ?
Je ne suis pas certain de comprendre ta question. Ce que je souhaite faire au final, dans mon projet, est d'intercepter un clic droit à une certaine position du curseur de la souris. Par exemple, intercepter le clic lorsque le curseur de la souris est dans le coin supérieur gauche de l'écran, c'est à dire au coordonnée X=0 et Y=0, afin de remplacer l'effet du clic par une commande perso, tel que l'ouverture du bloc note, ou la fermeture de la fenêtre active. Mais sous la forme d'un hook (0% cpu consommé) et non d'une commande en boucle qui analyserait en permanence car ça consomme beaucoup de ressource cpu.
Dernière modification par LukePerp (Le 18/03/2020, à 20:05)
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne
#10 Le 18/03/2020, à 21:02
- moko138
Re : [Résolu] Hook position souris
Merci. Ta réponse est claire.
%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel : À la découverte de dcraw
Hors ligne
#11 Le 19/03/2020, à 15:25
- LeoMajor
Re : [Résolu] Hook position souris
Par exemple, intercepter le clic lorsque le curseur de la souris est dans le coin supérieur gauche de l'écran, c'est à dire au coordonnée X=0 et Y=0, afin de remplacer l'effet du clic par une commande perso ...
tu récupères le focus de la manière suivante, beaucoup plus simple, avec le activex/widget, visible & invisible.
Public Sub ett_MouseMove(X As Integer, Y As Integer, Natif As Boolean)
Dim bt As Button
Print X, Y, Natif
'If Y = 0 Then Message("Bord SUPERIEUR")
If X <= 100 And Y <= 100 Then
With Fmain
.X = 0
.Y = 0
.W = 100
.H = 300
.Stacking = Window.Above
.Visible = True
End With
bt = New Button(Fmain) As "ebt"
With bt
.W = 30
.H = 30
.X = 5
.Y = 5
.Caption = "N"
.Font.Bold = True
.Visible = True
End With
Else
Fmain.Visible = False
Try bt.Delete()
Endif
End
Public Sub ebt_Click()
Dim app As String = "nautilus"
System.Shell = "/bin/bash"
Shell User.Home &/ "scripts/export-dbus-killapp.bash " & app Wait
Shell User.Home &/ "scripts/export-dbus-runapp.bash " & app
End
cat ~/scripts/export-dbus-killapp.bash
#!/bin/bash
if [ "$#" -ne 1 ]; then exit; fi
app="$1"
declare -a aexporter
active_session=$(loginctl --no-pager --no-legend list-sessions | awk '$2>=1000 {cmd="loginctl -p State -p Type show-session "$1; \
while (cmd|getline tmp)if(tmp~/active|x11/){sess[$1]++}; close(cmd)}; END {for (s in sess)if(sess[s]==2)print s}')
if [ -n "$active_session" ]; then
active_userid=$(loginctl -p User show-session "$active_session" | cut -d= -f2)
#active_pid=$(pgrep -u "$active_userid" gnome-session) # lightdm
active_pid=$(pgrep -u "$active_userid" gnome-session) #gdm3
aexporter=($(awk '/^(DBUS_SESSION_BUS_ADDRESS|DISPLAY|XAUTHORITY)/ ' < <(strings /proc/${active_pid}/environ)))
export "${aexporter[@]}"
killall "$app"
fi
cat ~/scripts/export-dbus-runapp.bash
#!/bin/bash
if [ "$#" -ne 1 ]; then exit; fi
app="$1"
declare -a aexporter
active_session=$(loginctl --no-pager --no-legend list-sessions | awk '$2>=1000 {cmd="loginctl -p State -p Type show-session "$1; \
while (cmd|getline tmp)if(tmp~/active|x11/){sess[$1]++}; close(cmd)}; END {for (s in sess)if(sess[s]==2)print s}')
if [ -n "$active_session" ]; then
active_userid=$(loginctl -p User show-session "$active_session" | cut -d= -f2)
#active_pid=$(pgrep -u "$active_userid" gnome-session) # lightdm
active_pid=$(pgrep -u "$active_userid" gnome-session) #gdm3
aexporter=($(awk '/^(DBUS_SESSION_BUS_ADDRESS|DISPLAY|XAUTHORITY)/ ' < <(strings /proc/${active_pid}/environ)))
export "${aexporter[@]}"
exec "$(which $app)" || /bin/bash "$app"
fi
tu es obligé de exporter le dbus comme pour cron, systemd.
Hors ligne
#12 Le 19/03/2020, à 16:49
- LukePerp
Re : [Résolu] Hook position souris
Léo, t'es au top ! Je vais étudier ton post plus tard. Pour le post 4, les routimes X_read et Y_read ne sont pas exécutée, est-ce correct ?
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne
#13 Le 21/03/2020, à 11:59
- LeoMajor
Re : [Résolu] Hook position souris
des propriétés en lecture seule .
sur du gambas récent, TextBox ( version 3.8 ) est à remplacer par TextLabel. Pas besoin également d'exporter le dbus. Donc les scripts précédents ne servent plus à rien.
Pour la démo, un bouton, et un menu,
Les "e*" comme "ett" sont les évènements de l'objet et également obj.Name. A remarquer que les évènements peuvent être "public" sans pour autant que la portée de la variable le soit obligatoirement (dim, private).
Public tt As New MouseIO As "ett"
Private tts As New TextLabel[]
'tolerance moniteur physique reglage/cadrage
' à adapter
Private d As Desktop
Private geox As Integer = d.W + d.X - CInt(d.W * 1 / 100)
Private geoy As Integer = d.H + d.Y - CInt(d.H * 1 / 100)
Public Sub init()
Dim i As Integer, ttn As TextLabel
Fmain.Stacking = Window.Normal
FMain.Tracking = True
For i = 1 To 3
ttn = New TextLabel(FMain) As "alltexlabels"
tts.Add(ttn)
With ttn
.Name = "T" & Str(i)
.H = 32
.W = 150
.Y = 40 * i
.X = 10
End With
Next
tt.Name = "MMouse"
End
Public Sub testa()
Dim item As TextLabel
For Each item In tts
Print item.Name, item.Parent.Name, item.X, item.Y, item.Enabled, item.Visible
Next
End
Public Sub Form_Open()
init()
testa()
Init_Menu()
'Gen_Menu()
End
Public Sub Form_MouseMove()
Dim mo As Mouse
tts[0].text = "X: " & mo.X & " " & tt.X & " " & tt.Native
tts[1].text = "Y: " & mo.Y & " " & tt.Y & " " & tt.Native
End
Public Sub Form_MouseDown()
Dim mo As Mouse
tts[2].text = "Button: " & mo.Button
End
Public Sub alltextlabels_Enter()
Dim focus As TextLabel
focus = Last
focus.Text = "Enter"
End
Public Sub ett_MouseMove(X As Integer, Y As Integer, Natif As Boolean)
Dim bt As Button
Print X, Y, Natif
'If X = 0 Then Message("Bord GAUCHE")
'If Y = 0 Then Message("Bord SUPERIEUR")
If X >= geox Then Message("Bord DROITE")
If Y >= geoy Then Message("Bord INFERIEUR")
If X <= 325 And Y <= 325 Then
With Fmain
.X = 0
.Y = 0
.W = 210
.H = 210
.Stacking = Window.Above
.Visible = True
End With
bt = New Button(Fmain) As "ebt"
With bt
.W = 30
.H = 30
.X = 5
.Y = 5
.Caption = String.Chr(26085) 'unicode
' chr="日"; printf "%s %i %s" "$chr" "$(printf "\x27")$chr" --->日 26085
' chr="日"; printf "%s %x %s" "$chr" "$(printf "\x27")$chr" -->日 65e5
.Font.Bold = True
.Visible = True
End With
Else
Fmain.Visible = False
Try bt.Delete()
Endif
End
Public Sub ebt_Click()
' gambas version 3.8
'Dim app As String = "nautilus"
'System.Shell = "/bin/bash"
'Shell User.Home &/ "scripts/export-dbus-killapp.bash " & app Wait
'Shell User.Home &/ "scripts/export-dbus-runapp.bash " & app
'gambas version 3.14
Dim app As String = "thunderbird"
If System.Exist(app) Then
Shell "killall " & app Wait
app = System.Find(app)
Exec [app]
End If
End
Public Sub Form_Leave()
tt.Start()
End
Public Sub Form_Enter()
tt.Stop()
End
Public Sub Init_Menu()
Dim m, ml As Menu
Dim n, nl As Menu
Dim l As String
Dim mllegend As String[] = ["firefox", "thunderbird", "gimp"]
Dim nllegend As String[] = ["a", "b", "c"]
'menu
m = New Menu(Fmain) As "em"
m.Text = "Menu"
m.Tag = "1"
For Each l In mllegend
ml = New Menu(m) As "eml"
ml.Text = l
ml.Tag = l
ml.Shortcut = "Key+" & Left(l, 1)
Next
'second menu
n = New Menu(m) As "en"
n.Text = "Autres"
n.Tag = "2"
For Each l In nllegend
nl = New Menu(n) As "enl"
nl.Text = l
nl.Tag = l
nl.Shortcut = "Key+" & Left(l, 1)
Next
End
Public Sub eml_Click()
Dim focus As Menu
focus = Last
'message(focus.Text)
Try Exec_Menu(focus.Text)
End
Public Sub enl_Click()
Dim focus As Menu
focus = Last
'message(focus.Text)
Try Exec_Menu(focus.Tag)
End
Public Sub Exec_Menu(appli As String)
If System.Exist(appli) Then
Shell "killall " & appli Wait
appli = System.Find(appli)
Exec [appli]
End If
End
Hors ligne
#14 Le 21/03/2020, à 12:42
- LukePerp
Re : [Résolu] Hook position souris
Léo, je n'avance pas aussi vite dans mon projet que toi sur mon projet !
Merci beaucoup ! Pour ton post 11, je te confirme que pour les évènements dans ebt_Click, je peux simplement les exécuter avec un shell, comme dans ton post 13 car j'ai la dernière version de gambas. Je vais étudier ton post 13 plus tard (j'ai un post de retard à chaque fois
En attendant, voici comment j'ai simplifié mon programme grâce à toi. La fenêtre n'est pas affichée, donc je n'utilise pas de bouton dessus. J'utilise la commande xinput, pour le moment, pour capturer le bouton cliqué. Je réfléchis à essayer xbindkeys pour comparer. Ensuite, je chercherai comment annuler l’effet du clic ordinaire pour le remplacer par ma commande perso (ouverture du bloc note dans cet exemple). Je pense utiliser xinput, en transposant le principe des fonctions ci-dessous.
' Gambas FMain file
Public tt As New MouseIO As "ett"
Private bFlag As Boolean
Public Sub Form_Activate()
tt.Start()
End
Public Sub ett_MouseMove(X As Integer, Y As Integer, Natif As Boolean)
Dim sClic As String
Dim sShell As String
' pour l'exemple ici avec Y>620 et le clic droit :
Me.Visible = False
If Y > 620 Then
sShell = "xinput --query-state 10 | grep 'button" & Chr(92) & "[3" & Chr(92) & "]=down' | cut -d'=' -f 2"
Shell sShell Wait To sClic
If Mid(sClic, 1, Len("down")) = "down" And bFlag = 0 Then
bFlag = 1
Print "Clic droit", X, Y, Natif, Timer
Shell "pluma" Wait 'pluma est le bloc note de Mate
Endif
Else
bFlag = 0
Endif
End
# Function to disable mouse right button
function DisableB3
{
if [ $bNormal -eq 1 ] ; then
bNormal=0
xinput set-button-map $MOUSE_ID 1 2 0
#echo "disable B3"
fi
}
# Function to enable mouse right button
function EnableB3
{
if [ $bNormal -eq 0 ] ; then
bNormal=1
FLAG=0
xinput set-button-map $MOUSE_ID 1 2 3
#echo "enable B3 $(date +%S)"
fi
}
Edit : voilà c'est terminé ! J'ai enfin un hook de la position de la souris avec interception du clic droit, ci-dessous le bout de code en gambas. Encore merci Léo ! La finalisation de mon projet sera facile à faire.
' Gambas FMain file
Public Sub Form_Activate()
bClicNormal = True
tt.Start()
End
Public Sub ett_MouseMove(X As Integer, Y As Integer, Natif As Boolean)
Dim sClic As String
Dim sShell As String
'Print X, Y, Natif, Timer
Me.Visible = False
If Y = 0 Then
DisableB3
sShell = "xinput --query-state 10 | grep 'button" & Chr(92) & "[3" & Chr(92) & "]=down' | cut -d'=' -f 2"
Shell sShell Wait To sClic
If Mid(sClic, 1, Len("down")) = "down" And bFlag = 0 Then
bFlag = 1
Print "Clic droit", X, Y, Natif, Timer
'Shell "firefox &" Wait
Endif
Else
bFlag = 0
EnableB3
Endif
End
Private Sub DisableB3()
If bClicNormal = True Then
bClicNormal = False
Shell "xinput set-button-map 10 1 2 0" Wait
Print "clic désactivé", Timer
Endif
End
Private Sub EnableB3()
If bClicNormal = False Then
bClicNormal = True
Shell "xinput set-button-map 10 1 2 3" Wait
Print "clic activé", Timer
Endif
End
Dernière modification par LukePerp (Le 21/03/2020, à 21:02)
Gamer inside - Ubuntu Mate dernière LTS - Intel i5, 16 Go - Dual boot Windows - Utilisateur de Dapps sur Ethereum
Hors ligne