gbx3: warning: circular references detected:
gbx3: 1 DBusStatusIcon
gbx3: 1 DBusStatusIconMenu
gbx3: 1 TrayIcon
gbx3: 4 DBusObject
gbx3: 2 Picture
gbx3: warning: 74 allocation(s) non freed.
..Ma parla di programmazione delle Xlib a basso livelloNell'esempio lì riportato si utilizzano in Gambas mediante la risorsa Extern le funzioni esterne del API del sistema grafico X11.
' Gambas class file
Public Struct XEventStruct
type As Integer
serial As Long
send_event As Boolean
display As Pointer
windowL As Long
root As Long
subwindow As Long
timeL As Long
x As Integer
y As Integer
x_root As Integer
y_root As Integer
state As Integer
keycode As Integer
same_screen As Boolean
End Struct
Private Enum KeyPress = 2, KeyRelease, ButtonPress, ButtonRelease, MotionNotify, EnterNotify, LeaveNotify,
FocusIn, FocusOut, KeymapNotify, Expose, GraphicsExpose, NoExpose
Private Const ExposureMask As Integer = 32768
Private Const KeyPressMask As Byte = 1
Private Const ButtonPressMask As Byte = 4
Extern XOpenDisplay(DpyName As String) As Pointer In "libX11"
Extern XDefaultScreen(Display As Pointer) As Integer In "libX11"
Extern XDefaultRootWindow(Display As Pointer) As Integer In "libX11"
Extern XSelectInput(Display As Pointer, Window As Integer, KeyMask As Long) In "libX11"
Private Extern XNextEvent(displayP As Pointer, event_return As XEventStruct) In "libX11"
Extern XGrabKey(Display As Pointer, KeyCode As Integer, Modifiers As Integer, Window As Pointer, OwnEvent As Boolean, PointerMode As Integer, KeyboardMode As Integer) In "libX11"
Extern XGrabKeyboard(Display As Pointer, KeyCode As Integer, Modifiers As Integer, Window As Pointer, OwnEvent As Boolean, PointerMode As Integer, KeyboardMode As Integer) In "libX11"
Extern XKeysymToKeycode(Display As Pointer, keysym As Integer) As Integer In "libX11"
Public Sub form_open()
Dim pDisplay As Pointer
Dim pRootWindow As Pointer
Dim pEvent As New XEventStruct
Dim keycode As Integer
pDisplay = XOpenDisplay(":0.0")
pRootWindow = XDefaultRootWindow(pDisplay)
keycode = XKeysymToKeycode(pDisplay, Asc("y"))
XGrabKey(pDisplay, keycode, 1, pRootWindow, False, 1, 1) '95 = F11 key, 1 = GrabModeAsync
XSelectInput(pDisplay, pRootWindow, KeyPressMask)
Do
XNextEvent(pDisplay, pEvent)
Debug pEvent.type
Loop
End
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
using namespace std;
int main()
{
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;
unsigned int modifiers = ControlMask | ShiftMask;
int keycode = XKeysymToKeycode(dpy,XK_Y);
Window grab_window = root;
Bool owner_events = False;
int pointer_mode = GrabModeAsync;
int keyboard_mode = GrabModeAsync;
XGrabKey(dpy, keycode, modifiers, grab_window, owner_events, pointer_mode,
keyboard_mode);
XSelectInput(dpy, root, KeyPressMask );
while(true)
{
bool shouldQuit = false;
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
cout << "Hot key pressed!" << endl;
XUngrabKey(dpy,keycode,modifiers,grab_window);
shouldQuit = true;
default:
break;
}
if(shouldQuit)
break;
}
XCloseDisplay(dpy);
return 0;
}
occhio al numlock, dev'essere spento perchè anche quello è un modificatoreSì, giusto. Bravo.
Library "libX11:6.3.0"
Private Enum KeyPress = 2, KeyRelease, ButtonPress, ButtonRelease, MotionNotify, EnterNotify, LeaveNotify,
FocusIn, FocusOut, KeymapNotify, Expose, GraphicsExpose, NoExpose
Private Const GrabModeAsync As Integer = 1
Private KeyPressMask As Integer = 1 * CInt(2 ^ 0) ' 1L<<0 '
Private ControlMask As Integer = 1 * CInt(2 ^ 2) ' 1<<2 '
Private ShiftMask As Integer = 1 * CInt(2 ^ 0) ' 1<<0 '
' Display *XOpenDisplay(char *display_name)'
' Opens a connection to the X server that controls a display.'
Private Extern XOpenDisplay(display_name As Pointer) As Pointer
' Window XDefaultRootWindow(Display *display)'
' Returns the root window for the default screen.'
Private Extern XDefaultRootWindow(display As Pointer) As Integer
' KeyCode XKeysymToKeycode(Display *display, KeySym keysym)'
' Obtains a KeyCode for a key having a specific KeySym.'
Private Extern XKeysymToKeycode(display As Pointer, keysym As Integer) As Integer
' XGrabKey(Display *display, int keycode, unsigned int modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode)'
' Passively grabs a single key of the keyboard.'
Private Extern XGrabKey(display As Pointer, keycode As Integer, modifiers As Integer, grab_window As Integer, owner_events As Boolean, pointermode As Integer, keyboard_mode As Integer)
' XSelectInput(Display *display, Window w, long event_mask)'
' Requests that the X server report the events associated with the specified event mask.'
Private Extern XSelectInput(display As Pointer, w As Integer, event_mask As Long)
' XNextEvent(Display *display, XEvent *event_return)'
' Gets the next event and remove it from the queue.'
Private Extern XNextEvent(display As Pointer, event_return As Pointer)
' XUngrabKey(Display *display, int keycode, unsigned int modifiers, Window grab_window)'
' Ungrabs a key.'
Private Extern XUngrabKey(display As Pointer, keycode As Integer, modifiers As Integer, Window As Pointer)
' XCloseDisplay(Display *display)'
' Closes a display or disconnects from the X server.'
Private Extern XCloseDisplay(display As Pointer)
Public Sub Main()
Dim dpy As Pointer
Dim root As Integer
Dim ev As Pointer
Dim keycode As Integer
ev = Alloc(192)
dpy = XOpenDisplay(0)
root = XDefaultRootWindow(dpy)
keycode = XKeysymToKeycode(dpy, Asc("y"))
XGrabKey(dpy, keycode, ControlMask Or ShiftMask, root, False, GrabModeAsync, GrabModeAsync)
XSelectInput(dpy, root, KeyPressMask)
While True
XNextEvent(dpy, ev)
Select Case Int@(ev)
Case KeyPress
Print "Hot key pressed !"
XUngrabKey(dpy, keycode, ControlMask Or ShiftMask, root)
Break
End Select
Wend
Free(ev)
XCloseDisplay(dpy)
End
' Gambas class file
Private xbindkeysp As Process
Private conf_file As String
Private hotkeys As Collection
Public Sub _new(conf As String)
If Not System.Exist("xbindkeys") Then
Debug "ERROR: xbindkeys not found in system path"
Quit
Endif
conf_file = conf
hotkeys = parse_conf()
If hotkeys = Null Then hotkeys = New Collection
Reload_xbindkeys()
End
Private Function parse_conf() As Collection
Dim pHotKeys As New Collection
Dim aLine As String
Dim WhatToDo As String 'find_new,find_action,find_hotkey
Dim action, hotkey As String
'Syntax:
'#new
'Action
'hotkey
If Not Exist(conf_file, True) Then Return Null
WhatToDo = "find_new"
For Each aLine In Split(File.Load(conf_file), "\n", "", True)
Select WhatToDo
Case "find_new"
If aLine = "#new" Then WhatToDo = "find_action"
Case "find_action"
action = aLine
WhatToDo = "find_hotkey"
Case "find_hotkey"
hotkey = aLine
pHotkeys[hotkey] = action
WhatToDo = "find_new"
End Select
Next
Return pHotKeys
End
Private Sub write_conf()
Dim outfile As String
Dim action As String
Dim HotKey As String
For Each Action In hotkeys
hotkey = hotkeys.key
outfile &= "#new" & "\n"
outfile &= Action & "\n"
outfile &= Hotkey & "\n"
Next
File.Save(conf_file, outfile)
End
Public Sub register(action As String) As String
Dim tmp As String = Temp()
Dim out As String
Dim splitted As String[]
Dim hotkey As String
Shell "touch " & tmp Wait
xbindkeysp.kill
Shell System.Find("xbindkeys") & " -k -f " & tmp To out
splitted = Split(out, "\n", "", True)
hotkey = Trim(splitted[splitted.count - 1])
hotkeys[hotkey] = "\"" & "echo " & action & "\""
write_conf()
Reload_xbindkeys()
Return hotkey
End
Public Sub close()
Try xbindkeysp.kill
End
Public Sub Reload_xbindkeys()
Try xbindkeysp.kill
xbindkeysp = Shell "xbindkeys -n -f " & conf_file For Read As "xbindkeysp"
End
Event HotkeyPressed(action As String)
Public Sub xbindkeysp_read()
Dim out As String
Line Input #xbindkeysp, out
Raise Hotkeypressed(out)
End
Public xb As XbindKeys
Public Sub Form_Open()
xb = New XbindKeys("/tmp/y") As "xb"
End
Public Sub Button1_Click()
xb.register("Prova_action")
End
Public Sub Form_Close()
xb.close
End
Public Sub xb_HotkeyPressed(action As String)
Debug action
End
Ora la missione è capire perchè il mio non andava
-EDIT-
Ok, era qualcosa riguardante la maschera in XgrabKey() mettendo la tua maschera, funge senza problemi.
' Gambas class file
Create Static
Static Public Description As String = "Example plugin" 'A description for this plugin
Static Public Friendly_name As String = "Example plugin" 'A friendly name for this plugin
Static Public configurable As Boolean = False 'Does this plugin provides a configure() method?
Public Sub _free()
End
Public Struct rItemT
plugin As String 'The plugin name
Text As String 'Text displayed in the clipboard
SubText As String 'Text displayed under the main text
Image_file As String 'Optional image displayed: possible values:
' "mimetype://fullpath/to/filename/to/identify"
' get picture from mime icon
' "desktopfile://fullpath/to/.desktop/file"
' Get the picture from .desktop file
' "resize://fullpath/to/image/file"
' Load the image from disk and resize it automatically
' "/fullpath/to/image/file"
' Load the image from disk
Clipboard_data As String 'The data copied to the clipboard
Action As String 'String that indicates what to do when activating a result:
'"DESKTOPOPEN"
' Open folders and starts .desktop files
'"EXEC"
' Executes executables files
'"GUESS"
' Choose an action based on filetype
'"NULL"
' Does nothing
Action_p As Variant 'the parameter for Action
End Struct
Private textcontrol As Object
Private plugin As String
Private iconsize As Integer
Private minchar As Integer = 3 'The plugin will not operate on searches smaller than that
Public Sub _new(p_plugin As String, p_iconsize As Integer)
plugin = p_plugin
iconsize = p_iconsize
End
Public Sub Stop()
'not sure if this is the right way, but this should be called when the plugin has to be unloaded
End
Private Sub trigged(query As String) As Boolean
'this function will decide if the plugin will be search for "query" or not.
If Len(query) < minchar Then Return False
'some more controls here (?)
Return True
End
Public Sub find(textcontrol As Object) As RItemT[]
'this is the main function, textcontrol is an object that exposes a "text" property.
'We need to pass an entire object reference instead of a simple string so that
'we can stop a (slow) plugin as soon as textcontrol.text changes (ie: the user is still typing...)
Dim anItem As String
Dim rResults As New RItemT[]
Dim rResult As RItemT
Dim current_search As String = textcontrol.text
If Not trigged(textcontrol.text) Then Return
For Each anItem In Dir(User.home).sort()
rResult = create_item(anItem)
If rResult <> Null Then rResults.Add(rResult)
'Wait 'if calculations are heavy a wait may be handy.
If textcontrol.text <> current_search Then Return
Next 'anItem
Return rResults
End
Private Function create_item(result As String) As RItemT
'this function creates an item that will be pushed into the result list.
Dim return_item As RItemT
return_item = New RItemT
return_item.plugin = plugin
return_item.Action = "EXEC" ' DESKTOPOPEN,EXEC,GUESS,NULL... MORE?
return_item.Action_p = "/usr/bin/gambas3"
return_item.Clipboard_data = "Some data copied to the clipboard"
return_item.image_file = "icon:/" & iconsize & "/bookmark"
return_item.Text = result
return_item.SubText = "In: " & User.home
Return return_item
End
Public Sub configure()
'this starts the configuration window.
'eg: plugin_template_gui.show()
End
~$ xbindkeys
Il programma "xbindkeys" non è attualmente installato. È possibile installarlo digitando:
sudo apt-get install xbindkeys
$ sudo apt-get install xbindkeys
/home/gian/.config/gambas3/higgins/xbindkeys_higgins: File o directory non esistente
FMain.load_plugin.109: PLUGIN_010_CALCULATOR
FMain.load_plugin.109: PLUGIN_020_APPS
FMain.load_plugin.109: PLUGIN_030_EXECUTABLE
FMain.load_plugin.109: PLUGIN_040_FBOOKMARKS
FMain.load_plugin.109: PLUGIN_050_LS
FMain.load_plugin.109: PLUGIN_090_INDEXER
FMain.load_plugin.109: PLUGIN_TEMPLATE
PLUGIN_090_INDEXER.reindex_timer_Timer.171: -61184844 minutes to go
PLUGIN_090_INDEXER.ReIndex.200: Indexing...
PLUGIN_090_INDEXER.ReIndex.201: sh -c ""
PLUGIN_090_INDEXER.reindex_timer_Timer.171: -61184844 minutes to go
PLUGIN_090_INDEXER.ReIndex.200: Indexing...
PLUGIN_090_INDEXER.ReIndex.201: sh -c ""
PLUGIN_090_INDEXER.indexprocess_kill.213: Finished indexing
PLUGIN_090_INDEXER.indexprocess_kill.213: Finished indexing
PLUGIN_090_INDEXER.reindex_timer_Timer.171: 30 minutes to go
Public Sub _new(conf As String, Optional alias As String = "")
If Not System.Exist("xbindkeys") Then
Debug "ERROR: xbindkeys not found in system path"
Quit
Endif
#!/bin/bash
#Simple locate plugin example.
#Put me in ~/.config/gambas3/higgins/extbin to use me
#This plugin will search for files using locate command, which has to be installed.
#This plugin will run only when the trigger is used, so:
# to search for "myfile.txt"
# write: l:myfile.txt
# (trigger is "l:")
#This plugin will not search anything lower than 3 characters (minchar=3)
export IFS=$'\n'
trigger="l:" #Search using the trigger? es: l:myfile
minchar=3 #Don't search on queries smaller than that, trigger does not count.
query="$@"
#Do we use a trigger?
if [ -n "$trigger" ] ; then
#...Yes, we do, so exit if not triggered
if [[ $query != $trigger* ]] ; then
exit
fi
#Strip the trigger prefix from the query
query=$(echo $query| sed "s/^$trigger//")
fi
len=${#query}
#Exit if the query is too small
if [ $len -lt $minchar ] ; then
exit ;
fi
#Finally, start the search:
for file in $(locate -i "$query") ; do
echo BEGIN
# For fields description and possible values, please refer to plugins/plugin_999_template
echo Text=$(basename $file)
echo SubText="in " $(dirname $file)"/"
echo Image_file="mimetype://$file"
echo Clipboard_data="$file"
echo Action="GUESS"
echo Action_p="$file"
echo END
done
# ~/.config/gambas3/higgins/extbin/locate.sh l:ciao
BEGIN
Text=ciao.srt
SubText=in /home/
Image_file=mimetype:///home/ciao.srt
Clipboard_data=/home/ciao.srt
Action=GUESS
Action_p=/home/ciao.srt
END
BEGIN
Text=ciao.ORIGINAL.srt
SubText=in /home/p2p/.aegisub/autoback/
Image_file=mimetype:///home/p2p/.aegisub/autoback/ciao.ORIGINAL.srt
Clipboard_data=/home/p2p/.aegisub/autoback/ciao.ORIGINAL.srt
Action=GUESS
Action_p=/home/p2p/.aegisub/autoback/ciao.ORIGINAL.srt
END