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 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)


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

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 ?


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

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


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

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

moko138 a écrit :

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)


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

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

moko138 a écrit :

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)


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

Hors ligne

#10 Le 18/03/2020, à 21:02

moko138

Re : [Résolu] Hook position souris

Merci. Ta réponse est claire.  smile


%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 ?


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

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 ! wink
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 wink
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)


Desktop & Laptop - Ubuntu Mate dernière LTS - Intel i5 - 16 Go - Dual boot Windows offline

Hors ligne