Grab mouse when clicking

This commit is contained in:
Daniel P. Berrange 2007-02-08 14:33:25 -05:00
parent 8118b4ac05
commit 29d8ae34c5
2 changed files with 104 additions and 6 deletions

View File

@ -23,6 +23,7 @@ import gtk.glade
import libvirt
import sys
import logging
import dbus
from vncViewer.vnc import GRFBViewer
@ -45,7 +46,8 @@ class vmmConsole(gobject.GObject):
topwin = self.window.get_widget("vmm-console")
topwin.hide()
topwin.set_title(vm.get_name() + " " + topwin.get_title())
self.title = vm.get_name() + " " + topwin.get_title()
topwin.set_title(self.title)
self.window.get_widget("control-shutdown").set_icon_widget(gtk.Image())
self.window.get_widget("control-shutdown").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_shutdown.png")
@ -53,6 +55,9 @@ class vmmConsole(gobject.GObject):
self.vncViewer = GRFBViewer(topwin, autograbkey=True)
else:
self.vncViewer = GRFBViewer(topwin, autograbkey=False)
self.vncViewer.connect("pointer-grabbed", self.notify_grabbed)
self.vncViewer.connect("pointer-ungrabbed", self.notify_ungrabbed)
self.window.get_widget("console-vnc-align").add(self.vncViewer)
self.vncViewer.connect("size-request", self.autosize)
self.vncViewer.show()
@ -109,6 +114,32 @@ class vmmConsole(gobject.GObject):
self.window.get_widget("console-vnc-vp").set_size_request(vncWidth+2, vncHeight+2)
def notify_grabbed(self, src):
topwin = self.window.get_widget("vmm-console")
try:
bus = dbus.SessionBus()
noteSvr = bus.get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
noteObj = dbus.Interface(noteSvr, "org.freedesktop.Notifications")
(x, y) = topwin.window.get_origin()
noteObj.Notify(topwin.get_title(),
0,
'',
"Pointer grabbed",
"The mouse pointer has been restricted to the virtual " +
"console window. To release the pointer press the key pair " +
"Ctrl+Alt",
[],
{"desktop-entry": "virt-manager",
"x": x+200, "y": y},
5 * 1000);
except Exception, e:
pass
topwin.set_title(_("Press Ctrl+Alt to release mouse.") + " " + self.title)
def notify_ungrabbed(self, src):
topwin = self.window.get_widget("vmm-console")
topwin.set_title(self.title)
def keygrab_changed(self, src, ignore1=None,ignore2=None,ignore3=None):
if self.config.get_console_keygrab() == 2:
self.vncViewer.set_autograb_keyboard(True)

View File

@ -174,7 +174,11 @@ class GRFBViewer(gtk.DrawingArea):
"connected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [str, int]),
"authenticated": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
"activated": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
"disconnected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [])
"disconnected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
"pointer-grabbed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
"pointer-ungrabbed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
"keyboard-grabbed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
"keyboard-ungrabbed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []),
}
def __init__(self, topwin, autograbkey=False):
@ -185,6 +189,7 @@ class GRFBViewer(gtk.DrawingArea):
self.authenticated = False
self.needpw = True
self.autograbkey = autograbkey
self.autograbptr = True
self.topwin = topwin
self.accel_groups = gtk.accel_groups_from_object(topwin)
self.preferred_encoding = (rfb.ENCODING_RAW, rfb.ENCODING_DESKTOP_RESIZE)
@ -197,9 +202,10 @@ class GRFBViewer(gtk.DrawingArea):
self.connect("expose-event", self.expose_region)
self.connect("motion-notify-event", self.update_pointer)
self.connect("button-press-event", self.update_pointer)
self.connect("button-release-event", self.update_pointer)
self.connect("motion-notify-event", self.pointer_move)
self.connect("button-press-event", self.pointer_press)
self.connect("button-release-event", self.pointer_release)
self.connect("scroll-event", self.pointer_scroll)
self.connect("key-press-event", self.key_press)
self.connect("key-release-event", self.key_release)
self.connect("enter-notify-event", self.enter_notify)
@ -265,6 +271,10 @@ class GRFBViewer(gtk.DrawingArea):
self.lastKeyVal = None
self.lastKeyRepeat = 0
empty = gtk.gdk.Pixmap(None, 1, 1, 1)
clear = gtk.gdk.Color()
self.nullcursor = gtk.gdk.Cursor(empty, empty, clear, clear, 0, 0)
self.set_events(gtk.gdk.EXPOSURE_MASK |
gtk.gdk.LEAVE_NOTIFY_MASK |
gtk.gdk.ENTER_NOTIFY_MASK |
@ -364,18 +374,48 @@ class GRFBViewer(gtk.DrawingArea):
mask = mask + 8
if state & gtk.gdk.BUTTON5_MASK:
mask = mask + 16
return mask
def take_screenshot(self):
return self.fb.clone_pixmap()
def pointer_move(self, win, event):
self.update_pointer(win, event)
def pointer_press(self, win, event):
if not gtk.gdk.pointer_is_grabbed() and self.will_autograb_pointer():
self.grab_pointer()
self.update_pointer(win, event)
def pointer_release(self, win, event):
self.update_pointer(win, event)
def pointer_scroll(self, win, event):
if self.client != None:
x, y, state = event.window.get_pointer()
newstate = state
if event.direction == gtk.gdk.SCROLL_UP:
newstate = newstate | gtk.gdk.BUTTON4_MASK
else:
newstate = newstate | gtk.gdk.BUTTON5_MASK
self.client.update_pointer(self.state_to_mask(newstate), x, y)
self.client.update_pointer(self.state_to_mask(state), x, y)
def update_pointer(self, win, event):
if self.client != None:
x, y, state = event.window.get_pointer()
self.client.update_pointer(self.state_to_mask(state), x, y)
return True
def will_autograb_pointer(self):
return self.autograbptr
def set_autograb_pointer(self, grab):
self.autograbptr = grab
if grab == False and gtk.gdk.pointer_is_grabbed():
self.ungrab_pointer()
def has_grabbed_keyboard(self):
return self.grabbedKeyboard
@ -384,18 +424,38 @@ class GRFBViewer(gtk.DrawingArea):
def set_autograb_keyboard(self, grab):
self.autograbkey = grab
if grab == False and grabbedKeyboard:
self.ungrab_keyboard()
def grab_pointer(self):
gtk.gdk.pointer_grab(self.window, False,
gtk.gdk.LEAVE_NOTIFY_MASK |
gtk.gdk.ENTER_NOTIFY_MASK |
gtk.gdk.BUTTON_RELEASE_MASK |
gtk.gdk.BUTTON_PRESS_MASK |
gtk.gdk.POINTER_MOTION_MASK |
gtk.gdk.POINTER_MOTION_HINT_MASK,
self.window, self.nullcursor)
self.emit("pointer-grabbed")
def ungrab_pointer(self):
gtk.gdk.pointer_ungrab()
self.emit("pointer-ungrabbed")
def grab_keyboard(self):
gtk.gdk.keyboard_grab(self.window, False, long(0))
for g in self.accel_groups:
self.topwin.remove_accel_group(g)
self.grabbedKeyboard = True
self.emit("keyboard-grabbed")
def ungrab_keyboard(self):
gtk.gdk.keyboard_ungrab()
for g in self.accel_groups:
self.topwin.add_accel_group(g)
self.grabbedKeyboard = False
self.emit("keyboard-ungrabbed")
def enter_notify(self, win, event):
if self.autograbkey:
@ -417,6 +477,13 @@ class GRFBViewer(gtk.DrawingArea):
def key_press(self, win, event):
# Allow Ctrl+Alt+Esc to break the pointer grab
if self.will_autograb_pointer():
if event.state & gtk.gdk.CONTROL_MASK and event.state & gtk.gdk.MOD1_MASK and gtk.gdk.pointer_is_grabbed():
self.ungrab_pointer()
return
self.ungrab_pointer()
# Key handling in VNC is screwy. The event.keyval from GTK is
# interpreted relative to modifier state. This really messes
# up with VNC which has no concept of modifiers. If we interpret