mirror of
https://github.com/rbreaves/kinto.git
synced 2025-08-06 02:48:26 +02:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cbb60668e3 | ||
![]() |
0275669be1 | ||
![]() |
3899fcf596 | ||
![]() |
20c93600e1 | ||
![]() |
c0bfec035f | ||
![]() |
eb576a6217 | ||
![]() |
b34dc4e928 | ||
![]() |
2ffe639024 | ||
![]() |
4c5cb36503 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@
|
||||
.DS_Store
|
||||
__pycache__/
|
||||
xkeysnail/
|
||||
keybindings_*
|
||||
mutter_*
|
||||
|
138
references/overlay.py
Normal file
138
references/overlay.py
Normal file
@@ -0,0 +1,138 @@
|
||||
import wx
|
||||
# import wx.richtext as rt
|
||||
# import images
|
||||
# http://www.ccp4.ac.uk/dist/checkout/wxPython-src-3.0.2.0/wxPython/demo/RichTextCtrl.py
|
||||
# https://stackoverflow.com/questions/40257359/how-to-dynamically-update-multiple-wxpython-static-text
|
||||
|
||||
def GetRoundBitmap( w, h, r ):
|
||||
maskColor = wx.Colour(0,0,0)
|
||||
shownColor = wx.Colour(5,5,5)
|
||||
b = wx.EmptyBitmap(w,h)
|
||||
dc = wx.MemoryDC(b)
|
||||
dc.SetBrush(wx.Brush(maskColor))
|
||||
dc.DrawRectangle(0,0,w,h)
|
||||
dc.SetBrush(wx.Brush(shownColor))
|
||||
dc.SetPen(wx.Pen(shownColor))
|
||||
dc.DrawRoundedRectangle(0,0,w,h,r)
|
||||
dc.SelectObject(wx.NullBitmap)
|
||||
b.SetMaskColour(maskColor)
|
||||
return b
|
||||
|
||||
def GetRoundShape( w, h, r ):
|
||||
return wx.Region( GetRoundBitmap(w,h,r) )
|
||||
|
||||
class PanelOne(wx.Panel):
|
||||
def __init__(self, parent):
|
||||
wx.Panel.__init__(self, parent)
|
||||
self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
|
||||
wx.StaticText(self, label = "'^⌘G - Select All (Ctrl-Cmd-G) ^⌘G - Select All (Ctrl-Cmd-G)\n^⌘G - Select All (Ctrl-Cmd-G) ^⌘G - Select All (Ctrl-Cmd-G)")
|
||||
self.SetTransparent( 220 )
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
self.Destroy()
|
||||
|
||||
class FancyFrame(wx.Frame):
|
||||
def __init__(self):
|
||||
sizer = wx.GridBagSizer()
|
||||
style = ( wx.CLIP_CHILDREN | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR |
|
||||
wx.NO_BORDER | wx.FRAME_SHAPED )
|
||||
wx.Frame.__init__(self, None, title='Fancy', style = style)
|
||||
|
||||
# self.rtc = rt.RichTextCtrl(self, style=wx.VSCROLL|wx.TE_READONLY|wx.HSCROLL|wx.NO_BORDER);
|
||||
# self.rtc.Disable()
|
||||
boldstatic = wx.Font(pointSize = 24, family = wx.DEFAULT,
|
||||
style = wx.BOLD, weight = wx.BOLD,
|
||||
faceName = 'Consolas')
|
||||
normalstatic = wx.Font(pointSize = 10, family = wx.DEFAULT,
|
||||
style = wx.NORMAL, weight = wx.NORMAL,
|
||||
faceName = 'Consolas')
|
||||
# font = wx.Font(pointSize = 18, family = wx.DEFAULT,
|
||||
# style = wx.NORMAL, weight = wx.NORMAL,
|
||||
# faceName = 'Consolas')
|
||||
self.SetFont(boldstatic)
|
||||
self.SetBackgroundColour((211,211,211))
|
||||
self.label = wx.StaticText(self, label = "^⌘G", pos = (100,50))
|
||||
self.SetFont(normalstatic)
|
||||
self.label2 = wx.StaticText(self, label = " - Select All (Ctrl-Cmd-G)", pos = (200,50))
|
||||
# sizer.Add(self.label, (4, 0), (1, 5), wx.EXPAND)
|
||||
# sizer.Add(self.label2, (5, 0), (1, 5), wx.EXPAND)
|
||||
# wx.StaticText(self, label = "^⌘G - Select All (Ctrl-Cmd-G) || ^⌘G - Select All (Ctrl-Cmd-G)\n^⌘G - Select All (Ctrl-Cmd-G) ^⌘G - Select All (Ctrl-Cmd-G)")
|
||||
# self.rtc.Bind(wx.EVT_SET_FOCUS,self.OnInput)
|
||||
# self.rtc.Bind(wx.EVT_KILL_FOCUS,self.OnInput)
|
||||
# self.rtc.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
|
||||
# self.rtc.BeginFontSize(14)
|
||||
# self.rtc.BeginBold()
|
||||
# self.rtc.WriteText("^⌘G")
|
||||
# self.rtc.EndBold()
|
||||
# self.rtc.BeginFontSize(10)
|
||||
# self.rtc.WriteText(" - Select All (Ctrl-Cmd-G)\n")
|
||||
# self.rtc.BeginFontSize(14)
|
||||
# self.rtc.WriteText("Different font sizes on the same line is allowed, too.")
|
||||
# self.rtc.EndFontSize()
|
||||
|
||||
# self.rtc.WriteText(" Next we'll show an indented paragraph.")
|
||||
|
||||
# self.rtc.BeginLeftIndent(60)
|
||||
# self.rtc.Newline()
|
||||
|
||||
# self.rtc.WriteText("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable.")
|
||||
# self.rtc.EndLeftIndent()
|
||||
# self.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.BOLD))
|
||||
# font = wx.Font(18, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
|
||||
# wx.text.SetFont(font)
|
||||
# self.panelOne = PanelOne(self)
|
||||
# self.SetFocus()
|
||||
w, h = wx.GetDisplaySize()
|
||||
self.SetSize((w/2, h/2))
|
||||
self.SetPosition( ((w-w/2)/2,(h-h/2)/2) )
|
||||
self.SetTransparent( 220 )
|
||||
|
||||
self.Bind(wx.EVT_KEY_UP, self.OnKeyDown)
|
||||
self.Bind(wx.EVT_MOTION, self.OnMouse)
|
||||
self.Bind(wx.EVT_PAINT, self.OnPaint)
|
||||
if wx.Platform == '__WXGTK__':
|
||||
self.Bind(wx.EVT_WINDOW_CREATE, self.SetRoundShape)
|
||||
else:
|
||||
self.SetRoundShape()
|
||||
|
||||
self.SetSizer(sizer)
|
||||
self.Show(True)
|
||||
|
||||
|
||||
def OnInput(self, e):
|
||||
self.Destroy()
|
||||
# e.Skip()
|
||||
|
||||
def SetRoundShape(self, event=None):
|
||||
w, h = self.GetSizeTuple()
|
||||
self.SetShape(GetRoundShape( w,h, 10 ) )
|
||||
|
||||
def OnPaint(self, event):
|
||||
dc = wx.PaintDC(self)
|
||||
dc = wx.GCDC(dc)
|
||||
w, h = self.GetSizeTuple()
|
||||
r = 10
|
||||
dc.SetPen( wx.Pen("#D3D3D3dth = 2"))
|
||||
dc.SetBrush( wx.Brush("#D3D3D3"))
|
||||
dc.DrawRoundedRectangle( 0,0,w,h,r )
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
# self.Close(force=True)
|
||||
self.Destroy()
|
||||
|
||||
def OnMouse(self, event):
|
||||
"""implement dragging"""
|
||||
if not event.Dragging():
|
||||
self._dragPos = None
|
||||
return
|
||||
self.CaptureMouse()
|
||||
if not self._dragPos:
|
||||
self._dragPos = event.GetPosition()
|
||||
else:
|
||||
pos = event.GetPosition()
|
||||
displacement = self._dragPos - pos
|
||||
self.SetPosition( self.GetPosition() - displacement )
|
||||
|
||||
app = wx.App()
|
||||
f = FancyFrame()
|
||||
app.MainLoop()
|
5
setup.py
5
setup.py
@@ -68,6 +68,8 @@ if len(check_x11) == 0:
|
||||
distro = cmdline("awk -F= '$1==\"NAME\" { print $2 ;}' /etc/os-release").replace('"','').strip().split(" ")[0]
|
||||
dename = cmdline("./system-config/dename.sh").replace('"','').strip().split(" ")[0].lower()
|
||||
|
||||
run_pkg = ""
|
||||
|
||||
def requirements(pkgm):
|
||||
print(bcolors.CYELLOW2 + "You need to install some packages, " +run_pkg+ ", for Kinto to fully remap browsers during input focus.\n" + bcolors.ENDC)
|
||||
print("sudo " + pkgm + " " + run_pkg + "\n")
|
||||
@@ -321,7 +323,7 @@ def kintoImpOne():
|
||||
|
||||
|
||||
runpkg = 0
|
||||
run_pkg = ""
|
||||
global run_pkg
|
||||
|
||||
if len(check_xbind) > 0 and len(check_xdotool) > 0 and len(check_ibus) > 0:
|
||||
print("Xbindkeys, xdotool and IBus requirement is installed.")
|
||||
@@ -337,6 +339,7 @@ def kintoImpOne():
|
||||
runpkg = 1
|
||||
|
||||
if runpkg != 0:
|
||||
print(runpkg)
|
||||
requirements(pkgm)
|
||||
|
||||
if not os.path.exists(homedir + '/.config/ibus/bus') and cmdline("ls ~/.config/ibus/bus -1rt") == "":
|
||||
|
@@ -12,7 +12,9 @@ GroupAdd, terminals, Fluent Terminal ahk_class ApplicationFrameWindow
|
||||
GroupAdd, posix, ahk_exe ubuntu.exe
|
||||
GroupAdd, posix, ahk_exe ConEmu.exe
|
||||
GroupAdd, posix, ahk_exe ConEmu64.exe
|
||||
GroupAdd, posix, ahk_exe Hyper.exe
|
||||
GroupAdd, posix, ahk_exe mintty.exe
|
||||
GroupAdd, posix, Fluent Terminal ahk_class ApplicationFrameWindow
|
||||
|
||||
GroupAdd, ConEmu, ahk_exe ConEmu.exe
|
||||
GroupAdd, ConEmu, ahk_exe ConEmu64.exe
|
||||
@@ -25,6 +27,34 @@ GroupAdd, editors, ahk_exe Code.exe
|
||||
GroupAdd, vscode, ahk_exe VSCodium.exe
|
||||
GroupAdd, vscode, ahk_exe Code.exe
|
||||
|
||||
; Close Apps
|
||||
^q::Send !{F4}
|
||||
|
||||
; Emoji Panel
|
||||
#^Space::Send {LWin down};{LWin up}
|
||||
|
||||
; Full Screenshot
|
||||
^+3::Send {PrintScreen}
|
||||
|
||||
; Region Screenshot
|
||||
^+4::Send #+{S}
|
||||
|
||||
; wordwise support
|
||||
$^Left::Send {Home}
|
||||
$^+Left::Send +{Home}
|
||||
$^Right::Send {End}
|
||||
$^+Right::Send +{End}
|
||||
^Up::Send ^{Home}
|
||||
^+Up::Send ^+{Home}
|
||||
^Down::Send ^{End}
|
||||
^+Down::Send ^+{End}
|
||||
^Backspace::Send +{Home}{Delete}
|
||||
!Backspace::Send ^{Backspace}
|
||||
!Left::Send ^{Left}
|
||||
!+Left::Send ^+{Left}
|
||||
!Right::Send ^{Right}
|
||||
!+Right::Send ^+{Right}
|
||||
|
||||
; Cmd+Space Alternative
|
||||
LWin & vk07::return
|
||||
LWin::return
|
||||
@@ -56,40 +86,15 @@ if(!GetKeyState("LWin", "P"))
|
||||
}
|
||||
return
|
||||
|
||||
; Close Apps
|
||||
^q::Send !{F4}
|
||||
|
||||
; Full Screenshot
|
||||
^+3::Send {PrintScreen}
|
||||
|
||||
; Region Screenshot
|
||||
^+4::Send #+{S}
|
||||
|
||||
; wordwise support
|
||||
$^Left::Send {Home}
|
||||
$^+Left::Send +{Home}
|
||||
$^Right::Send {End}
|
||||
$^+Right::Send +{End}
|
||||
^Up::Send ^{Home}
|
||||
^+Up::Send ^+{Home}
|
||||
^Down::Send ^{End}
|
||||
^+Down::Send ^+{End}
|
||||
^Backspace::Send +{Home}{Delete}
|
||||
!Backspace::Send ^{Backspace}
|
||||
!Left::Send ^{Left}
|
||||
!+Left::Send ^+{Left}
|
||||
!Right::Send ^{Right}
|
||||
!+Right::Send ^+{Right}
|
||||
|
||||
; ; Sublime Text Remaps for VS Code ; ST2CODE
|
||||
; #IfWinActive ahk_group vscode ; ST2CODE
|
||||
; ; Remap Ctrl+Shift to behave like macOS Sublimetext ; ST2CODE
|
||||
; ; Will extend cursor to multiple lines ; ST2CODE
|
||||
; #+Up::send ^!{Up} ; ST2CODE
|
||||
; #+Down::send ^!{Down} ; ST2CODE
|
||||
; ; Remap Ctrl+Cmd+G to select all matches ; ST2CODE
|
||||
; #^g::send ^+{L} ; ST2CODE
|
||||
; #If ; ST2CODE
|
||||
; Sublime Text Remaps for VS Code
|
||||
#IfWinActive ahk_group vscode ; ST2CODE
|
||||
; Remap Ctrl+Shift to behave like macOS Sublimetext
|
||||
; Will extend cursor to multiple lines
|
||||
#+Up::send ^!{Up} ; ST2CODE
|
||||
#+Down::send ^!{Down} ; ST2CODE
|
||||
; Remap Ctrl+Cmd+G to select all matches
|
||||
#^g::send ^+{L} ; ST2CODE
|
||||
#If ; ST2CODE
|
||||
|
||||
#IfWinActive ahk_exe sublime_text.exe
|
||||
; Remap Ctrl+Shift to behave like macOS Sublimetext
|
||||
@@ -101,22 +106,41 @@ $^+Right::Send +{End}
|
||||
#^g::send !{F3}
|
||||
#If
|
||||
|
||||
; Not sure why this fix is needed
|
||||
#IfWinActive ahk_exe Firefox.exe
|
||||
^v::send ^v
|
||||
#If
|
||||
|
||||
#IfWinActive ahk_group terminals
|
||||
; Copy
|
||||
^c::Send {LCtrl down}{LShift down}c{LCtrl Up}{LShift Up}
|
||||
#c::Send {LCtrl down}c{LCtrl Up}
|
||||
#IfWinNotActive ahk_group ConEmu
|
||||
; Paste
|
||||
^v::Send {LCtrl down}{LShift down}v{LCtrl Up}{LShift Up}
|
||||
#If
|
||||
$^v::
|
||||
If not WinActive("ahk_group ConEmu") && not WinActive("ahk_exe cmd.exe"){
|
||||
Send {LCtrl down}{LShift down}v{LCtrl Up}{LShift Up}
|
||||
}
|
||||
else{
|
||||
Send ^v
|
||||
}
|
||||
return
|
||||
#If
|
||||
|
||||
#IfWinActive ahk_group posix
|
||||
; Open/Close Tab for those that support it
|
||||
$^t::
|
||||
If not WinActive("ahk_group ConEmu"){
|
||||
Send {LCtrl down}{LShift down}t{LCtrl Up}{LShift Up}
|
||||
}
|
||||
else{
|
||||
Send ^t
|
||||
}
|
||||
return
|
||||
|
||||
$^w::
|
||||
If not WinActive("ahk_group ConEmu"){
|
||||
Send {LCtrl down}{LShift down}w{LCtrl Up}{LShift Up}
|
||||
}
|
||||
else{
|
||||
Send ^w
|
||||
}
|
||||
return
|
||||
|
||||
; End of Line
|
||||
#e::Send {LCtrl down}e{LCtrl Up}
|
||||
^e::return
|
||||
@@ -141,11 +165,11 @@ $^+Right::Send +{End}
|
||||
#z::Send {LCtrl down}z{LCtrl Up}
|
||||
#If
|
||||
|
||||
#IfWinActive ahk_group ConEmu
|
||||
; Paste
|
||||
$^v::Send {Shift down}{Insert}{Shift Up}
|
||||
#v::Send {LCtrl down}v{LCtrl Up}
|
||||
#If
|
||||
; #IfWinActive ahk_group ConEmu
|
||||
; ; Paste
|
||||
; $^v::Send {Shift down}{Insert}{Shift Up}
|
||||
; #v::Send {LCtrl down}v{LCtrl Up}
|
||||
; #If
|
||||
|
||||
#IfWinActive ahk_exe mintty.exe
|
||||
; Copy
|
||||
|
@@ -30,6 +30,7 @@ define_conditional_modmap(lambda wm_class: wm_class.casefold() not in terminals,
|
||||
# Key.RIGHT_CTRL: Key.RIGHT_META, # WinMac
|
||||
|
||||
# # KintoWin
|
||||
# Key.LEFT_CTRL: Key.RIGHT_CTRL, # KintoWin
|
||||
|
||||
# # Mac Only
|
||||
# Key.LEFT_META: Key.RIGHT_CTRL, # Mac
|
||||
@@ -44,7 +45,7 @@ define_conditional_modmap(re.compile(termStr, re.IGNORECASE), {
|
||||
# Key.LEFT_ALT: Key.RIGHT_CTRL, # Chromebook
|
||||
# # Left Ctrl Stays Left Ctrl
|
||||
# Key.LEFT_META: Key.LEFT_ALT, # Chromebook
|
||||
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # Chromebook
|
||||
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # Chromebook - Multi-language (Remove)
|
||||
# Key.RIGHT_CTRL: Key.RIGHT_ALT, # Chromebook
|
||||
# # Right Meta does not exist on chromebooks
|
||||
|
||||
@@ -52,7 +53,7 @@ define_conditional_modmap(re.compile(termStr, re.IGNORECASE), {
|
||||
# Key.LEFT_ALT: Key.RIGHT_CTRL, # WinMac
|
||||
# Key.LEFT_META: Key.LEFT_ALT, # WinMac
|
||||
# Key.LEFT_CTRL: Key.LEFT_CTRL, # WinMac
|
||||
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # WinMac
|
||||
# Key.RIGHT_ALT: Key.RIGHT_CTRL, # WinMac - Multi-language (Remove)
|
||||
# Key.RIGHT_META: Key.RIGHT_ALT, # WinMac
|
||||
# Key.RIGHT_CTRL: Key.LEFT_CTRL, # WinMac
|
||||
|
||||
@@ -166,10 +167,10 @@ define_keymap(re.compile(codeStr, re.IGNORECASE),{
|
||||
K("C-g"): K("f3"), # find_next
|
||||
K("Shift-f3"): pass_through_key, # cancel find_prev
|
||||
K("C-Shift-g"): K("Shift-f3"), # find_prev
|
||||
K("Super-C-g"): K("C-f2"), # Default - Sublime - find_all_under
|
||||
# K("Super-C-g"): K("C-f2"), # Default - Sublime - find_all_under
|
||||
# K("C-M-g"): K("C-f2"), # Chromebook - Sublime - find_all_under
|
||||
K("Super-Shift-up"): K("M-Shift-up"), # multi-cursor up
|
||||
K("Super-Shift-down"): K("M-Shift-down"), # multi-cursor down
|
||||
# K("Super-Shift-up"): K("M-Shift-up"), # multi-cursor up - Sublime
|
||||
# K("Super-Shift-down"): K("M-Shift-down"), # multi-cursor down - Sublime
|
||||
# K(""): pass_through_key, # cancel
|
||||
# K(""): K(""), #
|
||||
}, "Code")
|
||||
|
@@ -148,7 +148,26 @@ if [ $# -eq 0 ]; then
|
||||
set "$n"
|
||||
fi
|
||||
|
||||
# multi-language
|
||||
rightalt=false
|
||||
# VS code remap
|
||||
vssublime=false
|
||||
|
||||
if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "4" || $1 == "kintowin" || $1 == "winmac" || $1 == "mac" || $1 == "chromebook" ]]; then
|
||||
while true; do
|
||||
read -rep $'\nDo you want multi-language support (the right Alt key will not remap)? (y/N)\n' yn
|
||||
case $yn in
|
||||
[Yy]* ) rightalt=true; break;;
|
||||
* ) break;;
|
||||
esac
|
||||
done
|
||||
while true; do
|
||||
read -rep $'\nWould you like to give VS Code Sublime Text keymaps? (y/N)\n' yn
|
||||
case $yn in
|
||||
[Yy]* ) vssublime=true; break;;
|
||||
* ) break;;
|
||||
esac
|
||||
done
|
||||
branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
if [ "$branch" == "dev" ] || [ "$branch" == "alpha" ];then
|
||||
while true; do
|
||||
@@ -228,6 +247,10 @@ if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "4" || $1 == "kintowin" || $1
|
||||
sed -i "s/{username}/`whoami`/g" ~/.config/kinto/prexk.sh
|
||||
sed -i "s/{displayid}/`echo "$DISPLAY"`/g" ./xkeysnail-config/xkeysnail.service.new
|
||||
sed -i "s/{displayid}/`echo "$DISPLAY"`/g" ~/.config/kinto/prexk.sh
|
||||
|
||||
if $vssublime ; then
|
||||
perl -pi -e "s/(# )(.*)(- Sublime)/\$2\$3/g" ./xkeysnail-config/kinto.py.new >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $1 == "1" || $1 == "winmac" ]]; then
|
||||
@@ -251,6 +274,10 @@ elif [[ $1 == "4" || $1 == "kintowin" ]]; then
|
||||
perl -pi -e "s/(# )(.*)(# KintoWin)/\$2\$3/g" ./xkeysnail-config/kinto.py.new
|
||||
fi
|
||||
|
||||
if $rightalt ; then
|
||||
perl -pi -e "s/(\w.*)(Multi-language)/# \$1\$2/g" ./xkeysnail-config/kinto.py.new >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "4" || $1 == "kintowin" || $1 == "winmac" || $1 == "mac" || $1 == "chromebook" ]]; then
|
||||
mv ./xkeysnail-config/kinto.py.new ~/.config/kinto/kinto.py
|
||||
# if [ "$distro" == "fedora" ];then
|
||||
@@ -322,6 +349,13 @@ if [[ $1 == "1" || $1 == "2" || $1 == "3" || $1 == "4" || $1 == "kintowin" || $1
|
||||
echo "You can run 'sudo systemctl status xkeysnail' for more info"
|
||||
echo "You can also run 'sudo journalctl -u xkeysnail'"
|
||||
fi
|
||||
echo ""
|
||||
if $vssublime ; then
|
||||
echo -e "\e[1m\e[32mEnabled\e[0m VS Code Sublime Text remap."
|
||||
fi
|
||||
if $rightalt ; then
|
||||
echo -e "\e[1m\e[32mEnabled\e[0m mutli-language support."
|
||||
fi
|
||||
elif [[ $1 == "5" || $1 == "uninstall" || $1 == "Uninstall" ]]; then
|
||||
echo "Uninstalling Kinto - xkeysnail (udev)"
|
||||
uninstall
|
||||
|
Reference in New Issue
Block a user