Rework corner detection to use 1 pixel window.

This commit is contained in:
Marco Pesenti Gritti 2007-04-05 12:44:03 +02:00
parent 29d518eb55
commit 3a90cef5b6
4 changed files with 114 additions and 157 deletions

View File

@ -5,7 +5,7 @@ sugar_PYTHON = \
clipboardbox.py \ clipboardbox.py \
clipboardpanelwindow.py \ clipboardpanelwindow.py \
FriendsBox.py \ FriendsBox.py \
eventframe.py \ eventarea.py \
frame.py \ frame.py \
ZoomBox.py \ ZoomBox.py \
overlaybox.py \ overlaybox.py \

View File

@ -0,0 +1,106 @@
# Copyright (C) 2007, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import gtk
import gobject
import wnck
class EventArea(gobject.GObject):
__gsignals__ = {
'enter': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
'leave': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([]))
}
def __init__(self):
gobject.GObject.__init__(self)
self._windows = []
self._hover = False
right = gtk.gdk.screen_width() - 1
bottom = gtk.gdk.screen_height() -1
invisible = self._create_invisible(0, 0, 1, 1)
self._windows.append(invisible)
invisible = self._create_invisible(right, 0, 1, 1)
self._windows.append(invisible)
invisible = self._create_invisible(0, bottom, 1, 1)
self._windows.append(invisible)
invisible = self._create_invisible(right, bottom, 1, 1)
self._windows.append(invisible)
screen = wnck.screen_get_default()
screen.connect('active-window-changed',
self._active_window_changed_cb)
def _create_invisible(self, x, y, width, height):
invisible = gtk.Invisible()
invisible.connect('enter-notify-event', self._enter_notify_cb)
invisible.connect('leave-notify-event', self._leave_notify_cb)
invisible.drag_dest_set(0, [], 0)
invisible.connect('drag_motion', self._drag_motion_cb)
invisible.connect('drag_leave', self._drag_leave_cb)
invisible.realize()
invisible.window.set_events(gtk.gdk.POINTER_MOTION_MASK |
gtk.gdk.ENTER_NOTIFY_MASK |
gtk.gdk.LEAVE_NOTIFY_MASK)
invisible.window.move_resize(x, y, width, height)
return invisible
def _notify_enter(self):
if not self._hover:
self._hover = True
self.emit('enter')
def _notify_leave(self):
if self._hover:
self._hover = False
self.emit('leave')
def _enter_notify_cb(self, widget, event):
self._notify_enter()
def _leave_notify_cb(self, widget, event):
self._notify_leave()
def _drag_motion_cb(self, widget, drag_context, x, y, timestamp):
drag_context.drag_status(0, timestamp);
self._notify_enter()
return True
def _drag_leave_cb(self, widget, drag_context, timestamp):
self._notify_leave()
return True
def show(self):
for window in self._windows:
window.show()
def hide(self):
for window in self._windows:
window.hide()
def _active_window_changed_cb(self, screen):
for window in self._windows:
window.window.raise_()

View File

@ -1,149 +0,0 @@
# Copyright (C) 2007, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import gtk
import gobject
import wnck
class EventFrame(gobject.GObject):
__gsignals__ = {
'enter-edge': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
'enter-corner': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([])),
'leave': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ([]))
}
HOVER_NONE = 0
HOVER_CORNER = 1
HOVER_EDGE = 2
_THICKNESS = 6
def __init__(self):
gobject.GObject.__init__(self)
self._windows = []
self._hover = EventFrame.HOVER_NONE
self._active = False
invisible = self._create_invisible(0, 0,
gtk.gdk.screen_width(),
EventFrame._THICKNESS)
self._windows.append(invisible)
invisible = self._create_invisible(0, 0,
EventFrame._THICKNESS,
gtk.gdk.screen_height())
self._windows.append(invisible)
invisible = self._create_invisible(gtk.gdk.screen_width() - \
EventFrame._THICKNESS, 0,
gtk.gdk.screen_width(),
gtk.gdk.screen_height())
self._windows.append(invisible)
invisible = self._create_invisible(0, gtk.gdk.screen_height() - \
EventFrame._THICKNESS,
gtk.gdk.screen_width(),
gtk.gdk.screen_height())
self._windows.append(invisible)
screen = wnck.screen_get_default()
screen.connect('active-window-changed',
self._active_window_changed_cb)
def _create_invisible(self, x, y, width, height):
invisible = gtk.Invisible()
invisible.connect('motion-notify-event', self._motion_notify_cb)
invisible.connect('enter-notify-event', self._enter_notify_cb)
invisible.connect('leave-notify-event', self._leave_notify_cb)
invisible.drag_dest_set(0, [], 0)
invisible.connect('drag_motion', self._drag_motion_cb)
invisible.connect('drag_leave', self._drag_leave_cb)
invisible.realize()
invisible.window.set_events(gtk.gdk.POINTER_MOTION_MASK |
gtk.gdk.ENTER_NOTIFY_MASK |
gtk.gdk.LEAVE_NOTIFY_MASK)
invisible.window.move_resize(x, y, width, height)
return invisible
def _enter_notify_cb(self, widget, event):
self._check_position(widget, event.x, event.y)
def _motion_notify_cb(self, widget, event):
self._check_position(widget, event.x, event.y)
def _drag_motion_cb(self, widget, drag_context, x, y, timestamp):
drag_context.drag_status(0, timestamp);
self._check_position(widget, x, y)
return True
def _check_position(self, widget, x, y):
screen_w = gtk.gdk.screen_width()
screen_h = gtk.gdk.screen_height()
[screen_x, screen_y] = widget.window.get_origin()
screen_x += x
screen_y += y
if (screen_x == 0 and screen_y == 0) or \
(screen_x == 0 and screen_y == screen_h - 1) or \
(screen_x == screen_w - 1 and screen_y == 0) or \
(screen_x == screen_w - 1 and screen_y == screen_h - 1):
if self._hover != EventFrame.HOVER_CORNER:
self._hover = EventFrame.HOVER_CORNER
self.emit('enter-corner')
elif screen_x == 0 or \
screen_y == 0 or \
screen_x == screen_w - 1 or \
screen_y == screen_h - 1:
if self._hover != EventFrame.HOVER_EDGE:
self._hover = EventFrame.HOVER_EDGE
self.emit('enter-edge')
def _leave_notify_cb(self, widget, event):
self._notify_leave()
def _drag_leave_cb(self, widget, drag_context, timestamp):
self._notify_leave()
return True
def _notify_leave(self):
self._hover = EventFrame.HOVER_NONE
if self._active:
self.emit('leave')
def show(self):
self._active = True
for window in self._windows:
window.show()
def hide(self):
self._active = False
for window in self._windows:
window.hide()
def _active_window_changed_cb(self, screen):
for window in self._windows:
window.window.raise_()
def is_visible(self):
return self._windows[0].props.visible

View File

@ -19,7 +19,7 @@ import gtk
import gobject import gobject
import hippo import hippo
from view.frame.eventframe import EventFrame from view.frame.eventarea import EventArea
from view.frame.ActivitiesBox import ActivitiesBox from view.frame.ActivitiesBox import ActivitiesBox
from view.frame.ZoomBox import ZoomBox from view.frame.ZoomBox import ZoomBox
from view.frame.overlaybox import OverlayBox from view.frame.overlaybox import OverlayBox
@ -136,9 +136,9 @@ class Frame(object):
self._animator = None self._animator = None
self._hover = False self._hover = False
self._event_frame = EventFrame() self._event_area = EventArea()
self._event_frame.connect('enter-corner', self._enter_corner_cb) self._event_area.connect('enter', self._enter_corner_cb)
self._event_frame.show() self._event_area.show()
self._popup_context = FramePopupContext() self._popup_context = FramePopupContext()
self._popup_context.connect('activated', self._popup_context.connect('activated',
@ -173,7 +173,7 @@ class Frame(object):
self._animator.add(_Animation(self, 0.0)) self._animator.add(_Animation(self, 0.0))
self._animator.start() self._animator.start()
self._event_frame.show() self._event_area.show()
self.visible = False self.visible = False
if force: if force:
@ -192,7 +192,7 @@ class Frame(object):
self._animator.add(_Animation(self, 1.0)) self._animator.add(_Animation(self, 1.0))
self._animator.start() self._animator.start()
self._event_frame.hide() self._event_area.hide()
self.visible = True self.visible = True
self.mode = MODE_FORCE self.mode = MODE_FORCE
@ -336,7 +336,7 @@ class Frame(object):
def _drag_leave_cb(self, window, drag_context, timestamp): def _drag_leave_cb(self, window, drag_context, timestamp):
self._mouse_listener.mouse_leave() self._mouse_listener.mouse_leave()
def _enter_corner_cb(self, event_frame): def _enter_corner_cb(self, event_area):
self._mouse_listener.mouse_enter() self._mouse_listener.mouse_enter()
def notify_key_press(self): def notify_key_press(self):