예제 #1
0
    def _get_xembed_background_image(self):
        """ load the desktop background image in Unity """
        try:
            pixbuf = self._xid_background_image
        except AttributeError:
            size, size_mm = get_monitor_dimensions(self)
            filename = config.get_desktop_background_filename()
            if not filename:
                pixbuf = None
            else:
                try:
                    # load image
                    pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)

                    # Scale image to mimic the behavior of gnome-screen-saver.
                    # Take the largest, aspect correct, centered rectangle
                    # that fits on the monitor.
                    rm = Rect(0, 0, size[0], size[1])
                    rp = Rect(0, 0, pixbuf.get_width(), pixbuf.get_height())
                    ra = rm.inscribe_with_aspect(rp)
                    pixbuf = pixbuf.new_subpixbuf(*ra)
                    pixbuf = pixbuf.scale_simple(size[0], size[1],
                                                GdkPixbuf.InterpType.BILINEAR)
                except Exception as ex: # private exception gi._glib.GError when
                                        # librsvg2-common wasn't installed
                    _logger.error("_get_xembed_background_image(): " + \
                                unicode_str(ex))
                    pixbuf = None

            self._xid_background_image = pixbuf

        return pixbuf
예제 #2
0
    def _draw_side_bars(self, context):
        """
        Transparent bars left and right of the aspect corrected
        keyboard frame.
        """
        rgba = self.get_background_rgba()
        rgba[3] = 0.5
        rwin = Rect(0, 0,
                    self.get_allocated_width(),
                    self.get_allocated_height())
        rframe = self.get_keyboard_frame_rect()

        if rwin.w > rframe.w:
            r = rframe.copy()
            context.set_source_rgba(*rgba)
            context.set_line_width(0)

            r.x = rwin.left()
            r.w = rframe.left() - rwin.left()
            context.rectangle(*r)
            context.fill()

            r.x = rframe.right()
            r.w = rwin.right() - rframe.right()
            context.rectangle(*r)
            context.fill()
예제 #3
0
    def _get_xembed_background_image(self):
        """ load the desktop background image in Unity """
        try:
            pixbuf = self._xid_background_image
        except AttributeError:
            size, size_mm = get_monitor_dimensions(self)
            filename = config.get_desktop_background_filename()
            if not filename or \
               size[0] <= 0 or size[1] <= 0:
                pixbuf = None
            else:
                try:
                    # load image
                    pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)

                    # Scale image to mimic the behavior of gnome-screen-saver.
                    # Take the largest, aspect correct, centered rectangle
                    # that fits on the monitor.
                    rm = Rect(0, 0, size[0], size[1])
                    rp = Rect(0, 0, pixbuf.get_width(), pixbuf.get_height())
                    ra = rm.inscribe_with_aspect(rp)
                    pixbuf = pixbuf.new_subpixbuf(*ra)
                    pixbuf = pixbuf.scale_simple(size[0], size[1],
                                                 GdkPixbuf.InterpType.BILINEAR)
                except Exception as ex:  # private exception gi._glib.GError when
                    # librsvg2-common wasn't installed
                    _logger.error("_get_xembed_background_image(): " + \
                                unicode_str(ex))
                    pixbuf = None

            self._xid_background_image = pixbuf

        return pixbuf
예제 #4
0
    def _calc_bounds(self):
        """
        Compute the bounding box of the path.

        Doctests:
        # Simple move_to path, something inkscape would create.
        >>> p = KeyPath.from_svg_path("m 100,200 10,-10 z")
        >>> print(p.get_bounds())
        Rect(x=100.0 y=190.0 w=10.0 h=10.0)
        """

        try:
            xmin = xmax = self.segments[0][1][0]
            ymin = ymax = self.segments[0][1][1]
        except IndexError:
            return Rect()

        for command in self.segments:
            coords = command[1]
            for i in range(0, len(coords), 2):
                x = coords[i]
                y = coords[i + 1]
                if xmin > x:
                    xmin = x
                if xmax < x:
                    xmax = x
                if ymin > y:
                    ymin = y
                if ymax < y:
                    ymax = y

        return Rect(xmin, ymin, xmax - xmin, ymax - ymin)
예제 #5
0
 def log_to_canvas_rect(self, rect):
     if rect.is_empty():
         return Rect()
     return Rect(self.log_to_canvas_x(rect.x),
                 self.log_to_canvas_y(rect.y),
                 self.scale_log_to_canvas_x(rect.w),
                 self.scale_log_to_canvas_y(rect.h))
예제 #6
0
    def _draw_side_bars(self, context):
        """
        Transparent bars left and right of the aspect corrected
        keyboard frame.
        """
        rgba = self.get_background_rgba()
        rgba[3] = 0.5
        rwin = Rect(0, 0, self.get_allocated_width(),
                    self.get_allocated_height())
        rframe = self.get_keyboard_frame_rect()

        if rwin.w > rframe.w:
            r = rframe.copy()
            context.set_source_rgba(*rgba)
            context.set_line_width(0)

            r.x = rwin.left()
            r.w = rframe.left() - rwin.left()
            context.rectangle(*r)
            context.fill()

            r.x = rframe.right()
            r.w = rwin.right() - rframe.right()
            context.rectangle(*r)
            context.fill()
예제 #7
0
    def _draw_themed_icon(self, cr, icon_rect, color_scheme):
        """ draw themed icon """
        keys = [RectKey("icon" + str(i)) for i in range(4)]

        # Default colors for the case when none of the icon keys
        # are defined in the color scheme.
        # background_rgba =  [1.0, 1.0, 1.0, 1.0]
        fill_rgbas = [[0.9, 0.7, 0.0, 0.75], [1.0, 1.0, 1.0, 1.0],
                      [1.0, 1.0, 1.0, 1.0], [0.0, 0.54, 1.0, 1.0]]
        stroke_rgba = [0.0, 0.0, 0.0, 1.0]
        label_rgba = [0.0, 0.0, 0.0, 1.0]

        themed = False
        if color_scheme:
            if any(color_scheme.is_key_in_scheme(key) for key in keys):
                themed = True

        # four rounded rectangles
        rects = Rect(0.0, 0.0, 100.0, 100.0).deflate(5) \
                                            .subdivide(2, 2, 6)
        cr.save()
        cr.scale(icon_rect.w / 100., icon_rect.h / 100.0)
        cr.translate(icon_rect.x, icon_rect.y)
        cr.select_font_face("sans-serif")
        cr.set_line_width(2)

        for i, key in enumerate(keys):
            rect = rects[i]

            if themed:
                fill_rgba = color_scheme.get_key_rgba(key, "fill")
                stroke_rgba = color_scheme.get_key_rgba(key, "stroke")
                label_rgba = color_scheme.get_key_rgba(key, "label")
            else:
                fill_rgba = fill_rgbas[i]

            roundrect_arc(cr, rect, 5)
            cr.set_source_rgba(*fill_rgba)
            cr.fill_preserve()

            cr.set_source_rgba(*stroke_rgba)
            cr.stroke()

            if i == 0 or i == 3:
                if i == 0:
                    letter = "O"
                else:
                    letter = "B"

                cr.set_font_size(25)
                (x_bearing, y_bearing, _width, _height, x_advance,
                 y_advance) = cr.text_extents(letter)
                r = rect.align_rect(Rect(0, 0, _width, _height), 0.3, 0.33)
                cr.move_to(r.x - x_bearing, r.y - y_bearing)
                cr.set_source_rgba(*label_rgba)
                cr.show_text(letter)
                cr.new_path()

        cr.restore()
    def _on_draw(self, widget, cr):
        """
        Draw the onboard icon.
        """
        if not Gtk.cairo_should_draw_window(cr, self.get_window()):
            return False

        rect = Rect(0.0, 0.0, float(self.get_allocated_width()),
                    float(self.get_allocated_height()))
        color_scheme = self.get_color_scheme()

        # clear background
        cr.save()
        cr.set_operator(cairo.OPERATOR_CLEAR)
        cr.paint()
        cr.restore()

        # draw background color
        background_rgba = list(color_scheme.get_icon_rgba("background"))

        if Gdk.Screen.get_default().is_composited():
            background_rgba[3] *= 0.75
            cr.set_source_rgba(*background_rgba)

            corner_radius = min(rect.w, rect.h) * 0.1

            roundrect_arc(cr, rect, corner_radius)
            cr.fill()

            # decoration frame
            line_rect = rect.deflate(2)
            cr.set_line_width(2)
            roundrect_arc(cr, line_rect, corner_radius)
            cr.stroke()
        else:
            cr.set_source_rgba(*background_rgba)
            cr.paint()

        # draw themed icon
        self._draw_themed_icon(cr, rect, color_scheme)

        # draw dwell progress
        rgba = [0.8, 0.0, 0.0, 0.5]
        bg_rgba = [0.1, 0.1, 0.1, 0.5]
        if color_scheme:
            key = RectKey(
                "icon0")  # take dwell color from the first icon "key"
            rgba = color_scheme.get_key_rgba(key, "dwell-progress")
            rgba[3] = min(0.75, rgba[3])  # more transparency

            key = RectKey("icon1")
            bg_rgba = color_scheme.get_key_rgba(key, "fill")
            bg_rgba[3] = min(0.75, rgba[3])  # more transparency

        dwell_rect = rect.grow(0.5)
        self._dwell_progress.draw(cr, dwell_rect, rgba, bg_rgba)

        return True
예제 #9
0
파일: AutoShow.py 프로젝트: jegger/onboard
    def _find_close_position(self, view, home,
                             app_rect, acc_rect, limit_rects,
                             test_clearance, move_clearance,
                             horizontal = True, vertical = True):
        rh = home
        move_clearance = Rect(10, 10, 10, 10)

        # Leave a different clearance for the new, yet to be found, positions.
        ra = acc_rect.apply_border(*move_clearance)
        rp = app_rect.apply_border(*move_clearance)

        # candidate positions
        vp = []
        if vertical:
            xc = acc_rect.get_center()[0] - rh.w / 2
            if app_rect.w > rh.w:
                xc = max(xc, app_rect.left())
                xc = min(xc, app_rect.right() - rh.w)

            # below window
            vp.append([xc, rp.bottom(), app_rect])

            # above window
            vp.append([xc, rp.top() - rh.h, app_rect])

            # inside maximized window, y at home.y
            vp.append([xc, home.y, acc_rect])
            # vp.append([xc, rp.bottom()-ymargin, app_rect.deflate(rh.h+move_clearance[3]+ymargin)])

            # below text entry
            vp.append([xc, ra.bottom(), acc_rect])

            # above text entry
            vp.append([xc, ra.top() - rh.h, acc_rect])

        # limited, non-intersecting candidate rectangles
        rresult = None
        for p in vp:
            pl = view.limit_position(p[0], p[1],
                                     view.canvas_rect,
                                     limit_rects)
            r = Rect(pl[0], pl[1], rh.w, rh.h)
            ri = p[2]
            rcs = [ri, acc_rect] # collision rects
            if not any(r.intersects(rc) for rc in rcs):
                rresult = r
                break

        if rresult is None:
            # try again, this time horizontally and vertically
            rhtmp = Rect(vp[0][0], vp[0][1], home.w, home.h)
            return self._find_non_occluding_position(view, home,
                                                acc_rect, limit_rects,
                                                test_clearance, move_clearance,
                                                horizontal, vertical)
        else:
            return rresult.get_position()
예제 #10
0
    def _find_non_occluding_position(self,
                                     view,
                                     home,
                                     acc_rect,
                                     limit_rects,
                                     test_clearance,
                                     move_clearance,
                                     horizontal=True,
                                     vertical=True):
        rh = home

        # Leave some clearance around the accessible to account for
        # window frames and position errors of firefox entries.
        ra = acc_rect.apply_border(*test_clearance)

        if rh.intersects(ra):

            # Leave a different clearance for the new,
            # yet to be found positions.
            ra = acc_rect.apply_border(*move_clearance)
            x, y = rh.get_position()

            # candidate positions
            vp = []
            if horizontal:
                vp.append([ra.left() - rh.w, y])
                vp.append([ra.right(), y])
            if vertical:
                vp.append([x, ra.top() - rh.h])
                vp.append([x, ra.bottom()])

            # limited, non-intersecting candidate rectangles
            vr = []
            for p in vp:
                pl = view.limit_position(p[0], p[1], view.canvas_rect,
                                         limit_rects)
                r = Rect(pl[0], pl[1], rh.w, rh.h)
                if not r.intersects(ra):
                    vr.append(r)

            # candidate with smallest center-to-center distance wins
            chx, chy = rh.get_center()
            dmin = None
            rmin = None
            for r in vr:
                cx, cy = r.get_center()
                dx, dy = cx - chx, cy - chy
                d2 = dx * dx + dy * dy
                if dmin is None or dmin > d2:
                    dmin = d2
                    rmin = r

            if not rmin is None:
                return rmin.get_position()

        return None, None
예제 #11
0
    def get_repositioned_window_rect(self,
                                     view,
                                     home,
                                     limit_rects,
                                     test_clearance,
                                     move_clearance,
                                     horizontal=True,
                                     vertical=True):
        """
        Get the alternative window rect suggested by auto-show or None if
        no repositioning is required.
        """
        accessible = self._active_accessible
        if not accessible:
            return None

        accessible.invalidate_extents()
        acc_rect = accessible.get_extents()
        if acc_rect.is_empty() or \
           self._lock_visible:
            return None

        method = config.get_auto_show_reposition_method()
        x = None
        y = None

        # The home_rect doesn't include window decoration,
        # make sure to add decoration for correct clearance.
        rh = home.copy()
        window = view.get_kbd_window()
        if window:
            offset = window.get_client_offset()
            rh.w += offset[0]
            rh.h += offset[1]

        # "Follow active window" method
        if method == RepositionMethodEnum.REDUCE_POINTER_TRAVEL:
            frame = accessible.get_frame()
            app_rect = frame.get_extents() \
                if frame else Rect()
            x, y = self._find_close_position(view, rh, app_rect, acc_rect,
                                             limit_rects, test_clearance,
                                             move_clearance, horizontal,
                                             vertical)

        # "Only move when necessary" method
        if method == RepositionMethodEnum.PREVENT_OCCLUSION:
            x, y = self._find_non_occluding_position(view, rh, acc_rect,
                                                     limit_rects,
                                                     test_clearance,
                                                     move_clearance,
                                                     horizontal, vertical)
        if not x is None:
            return Rect(x, y, home.w, home.h)
        else:
            return None
예제 #12
0
    def _on_draw(self, widget, cr):
        """
        Draw the onboard icon.
        """
        if not Gtk.cairo_should_draw_window(cr, self.get_window()):
            return False

        rect = Rect(0.0, 0.0, float(self.get_allocated_width()), float(self.get_allocated_height()))
        color_scheme = self.get_color_scheme()

        # clear background
        cr.save()
        cr.set_operator(cairo.OPERATOR_CLEAR)
        cr.paint()
        cr.restore()

        # draw background color
        background_rgba = list(color_scheme.get_icon_rgba("background"))

        if Gdk.Screen.get_default().is_composited():
            background_rgba[3] *= 0.75
            cr.set_source_rgba(*background_rgba)

            corner_radius = min(rect.w, rect.h) * 0.1

            roundrect_arc(cr, rect, corner_radius)
            cr.fill()

            # decoration frame
            line_rect = rect.deflate(2)
            cr.set_line_width(2)
            roundrect_arc(cr, line_rect, corner_radius)
            cr.stroke()
        else:
            cr.set_source_rgba(*background_rgba)
            cr.paint()

        # draw themed icon
        self._draw_themed_icon(cr, rect, color_scheme)

        # draw dwell progress
        rgba = [0.8, 0.0, 0.0, 0.5]
        bg_rgba = [0.1, 0.1, 0.1, 0.5]
        if color_scheme:
            key = RectKey("icon0")  # take dwell color from the first icon "key"
            rgba = color_scheme.get_key_rgba(key, "dwell-progress")
            rgba[3] = min(0.75, rgba[3])  # more transparency

            key = RectKey("icon1")
            bg_rgba = color_scheme.get_key_rgba(key, "fill")
            bg_rgba[3] = min(0.75, rgba[3])  # more transparency

        dwell_rect = rect.grow(0.5)
        self._dwell_progress.draw(cr, dwell_rect, rgba, bg_rgba)

        return True
예제 #13
0
    def __init__(self):
        # logical rectangle as defined by the keyboard layout,
        # never changed after loading.
        self.initial_log_rect = Rect(0.0, 0.0, 1.0, 1.0)  # includes border

        # logical rectangle as defined by the keyboard layout
        self.log_rect = Rect(0.0, 0.0, 1.0, 1.0)  # includes border

        # canvas rectangle in drawing units
        self.canvas_rect = Rect(0.0, 0.0, 1.0, 1.0)
예제 #14
0
    def _on_draw(self, widget, context):

        if not LabelPopup._pango_layout:
            LabelPopup._pango_layout = Pango.Layout(context=Gdk.pango_context_get())

        rect = Rect(0, 0, self.get_allocated_width(),
                          self.get_allocated_height())
        content_rect = Rect(rect.x, rect.y, rect.w,
                            rect.h - rect.h * self.ARROW_HEIGHT)
        arrow_rect   = Rect(rect.x, content_rect.bottom(), rect.w,
                            rect.h * self.ARROW_HEIGHT) \
                       .deflate((rect.w - rect.w * self.ARROW_WIDTH) / 2.0, 0)

        label_rect = content_rect.deflate(rect.w * self.LABEL_MARGIN)

        # background
        if config.scanner.color_type == "custom_color" and config.scanner.enabled == True:
            # scan label popup color
            color_rgba = []
            for val in config.scanner.scan_color:
                color_rgba.append(val)
            
            rgb = color_rgba[:3]
            opacity = color_rgba[3]
            fill = rgb + [opacity]
        else:
            fill = self._key.get_fill_color()

        context.save()
        context.set_operator(cairo.OPERATOR_CLEAR)
        context.paint()
        context.restore()

        context.set_source_rgba(*fill)
        roundrect_arc(context, content_rect, config.CORNER_RADIUS)
        context.fill()

        l, t, r, b = arrow_rect.to_extents()
        t -= 1
        context.move_to(l, t)
        context.line_to(r, t)
        context.line_to((l+r) / 2, b)
        context.fill()

        # draw label/image
        label_color = self._key.get_label_color()
        pixbuf = self._key.get_image(label_rect.w, label_rect.h)
        if pixbuf:
            self._draw_image(context, pixbuf, label_rect, label_color)
        else:
            label = self._key.get_label()
            if label:
                if label == " ":
                    label = "␣"
                self._draw_text(context, label, label_rect, label_color)
    def get_accessible_extents(accessible):
        """ Screen rect of the given accessible, no caching """
        try:
            ext = accessible.get_extents(Atspi.CoordType.SCREEN)
        except Exception as ex:  # private exception gi._glib.GError when
            # right clicking onboards unity2d launcher (Precise)
            _logger.info("Invalid accessible,"
                         " failed to get extents: " + unicode_str(ex))
            return Rect()

        return Rect(ext.x, ext.y, ext.width, ext.height)
예제 #16
0
 def get_keyboard_frame_rect(self):
     """
     Rectangle of the potentially aspect-corrected
     frame around the layout.
     """
     layout = self.get_layout()
     if layout:
         rect = layout.get_canvas_border_rect()
         rect = rect.inflate(self.get_frame_width())
     else:
         rect = Rect(0, 0, self.get_allocated_width(),
                           self.get_allocated_height())
     return rect.int()
예제 #17
0
def canvas_to_root_window_rect(window, rect):
    """
    Convert rect in canvas coordinates to root window coordinates.
    """
    gdk_win = window.get_window()
    if gdk_win:
        x0, y0 = gdk_win.get_root_coords(rect.x, rect.y)
        x1, y1 = gdk_win.get_root_coords(rect.x + rect.w, rect.y + rect.h)
        rect = Rect.from_extents(x0, y0, x1, y1)
    else:
        rect = Rect()

    return rect
예제 #18
0
 def limit_size(self, rect):
     """
     Limit the given window rect to fit on screen.
     """
     screen = self.get_screen()
     limits = Rect(0, 0, screen.get_width(), screen.get_height())
     r = rect.copy()
     if not limits.is_empty():  # LP #1633284
         if r.w > limits.w:
             r.w = limits.w - 40
         if r.h > limits.h:
             r.h = limits.h - 20
     return r
예제 #19
0
 def get_keyboard_frame_rect(self):
     """
     Rectangle of the potentially aspect-corrected
     frame around the layout.
     """
     layout = self.get_layout()
     if layout:
         rect = layout.get_canvas_border_rect()
         rect = rect.inflate(self.get_frame_width())
     else:
         rect = Rect(0, 0, self.get_allocated_width(),
                     self.get_allocated_height())
     return rect.int()
예제 #20
0
파일: AutoShow.py 프로젝트: jegger/onboard
    def _find_non_occluding_position(self, view, home,
                                     acc_rect, limit_rects,
                                     test_clearance, move_clearance,
                                     horizontal = True, vertical = True):
        rh = home

        # Leave some clearance around the accessible to account for
        # window frames and position errors of firefox entries.
        ra = acc_rect.apply_border(*test_clearance)

        if rh.intersects(ra):

            # Leave a different clearance for the new, yet to be found, positions.
            ra = acc_rect.apply_border(*move_clearance)
            x, y = rh.get_position()

            # candidate positions
            vp = []
            if horizontal:
                vp.append([ra.left() - rh.w, y])
                vp.append([ra.right(), y])
            if vertical:
                vp.append([x, ra.top() - rh.h])
                vp.append([x, ra.bottom()])

            # limited, non-intersecting candidate rectangles
            vr = []
            for p in vp:
                pl = view.limit_position(p[0], p[1],
                                         view.canvas_rect,
                                         limit_rects)
                r = Rect(pl[0], pl[1], rh.w, rh.h)
                if not r.intersects(ra):
                    vr.append(r)

            # candidate with smallest center-to-center distance wins
            chx, chy = rh.get_center()
            dmin = None
            rmin = None
            for r in vr:
                cx, cy = r.get_center()
                dx, dy = cx - chx, cy - chy
                d2 = dx * dx + dy * dy
                if dmin is None or dmin > d2:
                    dmin = d2
                    rmin = r

            if not rmin is None:
                return rmin.get_position()

        return None, None
예제 #21
0
    def log_to_canvas_rect(self, rect):
        """ ~50% faster than the above. """
        w = rect.w
        h = rect.h
        if w <= 0 or h <= 0:
            return Rect()

        canvas_rect = self.canvas_rect
        log_rect = self.log_rect
        scale_w = canvas_rect.w / log_rect.w
        scale_h = canvas_rect.h / log_rect.h

        return Rect(canvas_rect.x + (rect.x - log_rect.x) * scale_w,
                    canvas_rect.y + (rect.y - log_rect.y) * scale_h,
                    w * scale_w, h * scale_h)
예제 #22
0
    def get_known_rects(self):
        """
        Return all rects that may have resulted from internal
        window moves, not from user controlled drag operations.
        """
        rects = list(self._known_window_rects)

        co = config.window.landscape
        rects.append(Rect(co.x, co.y, co.width, co.height))

        co = config.window.portrait
        rects.append(Rect(co.x, co.y, co.width, co.height))

        rects.append(self.home_rect)
        return rects
예제 #23
0
    def _find_non_occluding_position(self, home, acc_rect,
                                     vertical = True, horizontal = True):

        # Leave some clearance around the accessible to account for
        # window frames and position errors of firefox entries.
        ra = acc_rect.apply_border(*config.auto_show.widget_clearance)
        rh = home

        if rh.intersects(ra):
            x, y = rh.get_position()

            # candidate positions
            vp = []
            if horizontal:
                vp.append([ra.left() - rh.w, y])
                vp.append([ra.right(), y])
            if vertical:
                vp.append([x, ra.top() - rh.h])
                vp.append([x, ra.bottom()])

            # limited, non-intersecting candidate rectangles
            vr = []
            for p in vp:
                pl = self._keyboard.limit_position( p[0], p[1],
                                                  self._keyboard.canvas_rect)
                r = Rect(pl[0], pl[1], rh.w, rh.h)
                chx, chy = rh.get_center()
                cx, cy = r.get_center()
                d2 = cx * chx + cy * chy
                if not r.intersects(ra):
                    vr.append(r)

            # candidate with smallest center-to-center distance wins
            chx, chy = rh.get_center()
            dmin = None
            rmin = None
            for r in vr:
                cx, cy = r.get_center()
                dx, dy = cx - chx, cy - chy
                d2 = dx * dx + dy * dy
                if dmin is None or dmin > d2:
                    dmin = d2
                    rmin = r

            if not rmin is None:
                return rmin.get_position()

        return None, None
예제 #24
0
    def start_drag(self, point = None):

        # Find the pointer position for the occasions when we are
        # not being called from an event (move button).
        if not point:
            rootwin = Gdk.get_default_root_window()
            dunno, x_root, y_root, mask = rootwin.get_pointer()
            point = (x_root, y_root)

        # rmember pointer and window positions
        window = self.get_drag_window()
        x, y = window.get_position()
        self._drag_start_pointer = point
        self._drag_start_offset = [point[0] - x, point[1] - y]
        self._drag_start_rect = Rect.from_position_size(window.get_position(),
                                                        window.get_size())
        # not yet actually moving the window
        self._drag_active = False

        # get the threshold
        self._drag_threshold = self.get_drag_threshold()

        # check if the temporary threshold unlocking has expired
        if not self.drag_protection or \
           not self._temporary_unlock_time is None and \
           time.time() - self._temporary_unlock_time > \
                         self.temporary_unlock_delay:
            self._temporary_unlock_time = None

        # give keyboard window a chance to react
        self.on_drag_initiated()
예제 #25
0
    def _get_window_rect_for_accessible_rect(self,
                                             home,
                                             rect,
                                             limit_rects,
                                             test_clearance,
                                             move_clearance,
                                             horizontal=True,
                                             vertical=True):
        """
        Find new window position based on the screen rect of the accessible.
        """
        mode = "nooverlap"
        x = y = None

        if mode == "closest":
            x, y = rect.left(), rect.bottom()
        if mode == "nooverlap":
            x, y = self._find_non_occluding_position(home, rect, limit_rects,
                                                     test_clearance,
                                                     move_clearance,
                                                     horizontal, vertical)
        if not x is None:
            return Rect(x, y, home.w, home.h)
        else:
            return None
예제 #26
0
    def update_window_rect(self):
        """
        Call this on configure event, the only time when
        get_position, get_size, etc. can be trusted.
        """
        visible = self.is_visible()
        if visible:
            pos = Gtk.Window.get_position(self)
            size = Gtk.Window.get_size(self)
            origin = self.get_window().get_origin()
            if len(origin) == 3:  # What is the first parameter for? Gdk bug?
                origin = origin[1:]

            if _logger.isEnabledFor(logging.DEBUG):
                _logger.debug(
                    "update_window_rect1: pos {}, size {}, origin {}".format(
                        pos, size, origin))
            pos = self._apply_window_scaling_factor(pos)

            self._window_rect = Rect.from_position_size(pos, size)
            self._origin = origin
            self._client_offset = (origin[0] - pos[0], origin[1] - pos[1])
            self._screen_orientation = self.get_screen_orientation()

            if _logger.isEnabledFor(logging.DEBUG):
                _logger.debug("update_window_rect2: pos {}, client_offset {}, "
                              "screen_orientation {}".format(
                                  pos, self._client_offset,
                                  self._screen_orientation))
예제 #27
0
def get_monitor_rects(screen):
    """
    Screen limits, one rect per monitor. Monitors may have
    different sizes and arbitrary relative positions.
    """
    rects = []
    if screen:
        for i in range(screen.get_n_monitors()):
            r = screen.get_monitor_geometry(i)
            rects.append(Rect(r.x, r.y, r.width, r.height))
    else:
        rootwin = Gdk.get_default_root_window()
        r = Rect.from_position_size(rootwin.get_position(),
                                (rootwin.get_width(), rootwin.get_height()))
        rects.append(r)
    return rects
예제 #28
0
    def start_drag(self, point = None):
        self._monitor_rects = None

        # Find the pointer position for the occasions when we are
        # not being called from an event (move button).
        if not point:
            rootwin = Gdk.get_default_root_window()
            dunno, x_root, y_root, mask = rootwin.get_pointer()
            point = (x_root, y_root)

        # rmember pointer and window positions
        window = self.get_drag_window()
        x, y = window.get_position()
        self._drag_start_pointer = point
        self._drag_start_offset = [point[0] - x, point[1] - y]
        self._drag_start_rect = Rect.from_position_size(window.get_position(),
                                                        window.get_size())
        # not yet actually moving the window
        self._drag_active = False

        # get the threshold
        self._drag_threshold = self.get_drag_threshold()

        # check if the temporary threshold unlocking has expired
        if not self.drag_protection or \
           not self._temporary_unlock_time is None and \
           time.time() - self._temporary_unlock_time > \
                         self.temporary_unlock_delay:
            self._temporary_unlock_time = None

        # give keyboard window a chance to react
        self.on_drag_initiated()
예제 #29
0
    def update_position(self, canvas_rect):
        w, h = self._size
        w = min(w, canvas_rect.w / 3.0)
        w = min(w, canvas_rect.h / 3.0)
        h = w
        self._scale = 1.0

        xc, yc = canvas_rect.get_center()
        if self.id is Handle.MOVE:  # move handle?
            d = min(canvas_rect.w - 2.0 * w, canvas_rect.h - 2.0 * h)
            self._scale = 1.4
            w = min(w * self._scale, d)
            h = min(h * self._scale, d)

        if self.id in [Handle.WEST, Handle.NORTH_WEST, Handle.SOUTH_WEST]:
            x = canvas_rect.left()
        if self.id in [Handle.NORTH, Handle.NORTH_WEST, Handle.NORTH_EAST]:
            y = canvas_rect.top()
        if self.id in [Handle.EAST, Handle.NORTH_EAST, Handle.SOUTH_EAST]:
            x = canvas_rect.right() - w
        if self.id in [Handle.SOUTH, Handle.SOUTH_WEST, Handle.SOUTH_EAST]:
            y = canvas_rect.bottom() - h

        if self.id in [Handle.MOVE, Handle.EAST, Handle.WEST]:
            y = yc - h / 2.0
        if self.id in [Handle.MOVE, Handle.NORTH, Handle.SOUTH]:
            x = xc - w / 2.0

        self._rect = Rect(x, y, w, h)
    def _read_remaining_accessible_state(self, accessible):
        """
        Read more attributes and find out as much as we
        can about the accessibles purpose.
        """
        state = {}

        state["attributes"] = accessible.get_attributes()
        state["interfaces"] = accessible.get_interfaces()

        ext = accessible.get_extents(Atspi.CoordType.SCREEN)
        state["extents"] = Rect(ext.x, ext.y, ext.width, ext.height)

        # These are currently used only in debug output
        if _logger.isEnabledFor(logging.DEBUG):
            state["id"] = accessible.get_id()
            state["name"] = accessible.get_name()
            pid = accessible.get_process_id()
            state["process-id"] = pid
            if pid != -1:
                state["process-name"] = Process.get_process_name(pid)

            app = accessible.get_application()
            if app:
                state["app-name"] = app.get_name()
                state["app-description"] = app.get_description()

        return state
예제 #31
0
    def _on_draw(self, widget, context):
        #_logger.debug("Draw: clip_extents=" + str(context.clip_extents()))
        #self.get_window().set_debug_updates(True)

        if not Gtk.cairo_should_draw_window(context, self.get_window()):
            return

        clip_rect = Rect.from_extents(*context.clip_extents())

        # draw background
        decorated = self.draw_background(context)

        # On first run quickly overwrite the background only.
        # This gives a slightly smoother startup with desktop remnants
        # flashing though for a shorter time.
        if self._first_draw:
            self._first_draw = False
            self.queue_draw()
            return

        if not self.layout:
            return

        # run through all visible layout items
        layer_ids = self.layout.get_layer_ids()
        for item in self.layout.iter_visible_items():
            if item.layer_id:

                # draw layer background
                layer_index = layer_ids.index(item.layer_id)
                parent = item.parent
                if parent and \
                   layer_index != 0:
                    rect = parent.get_canvas_rect()
                    context.rectangle(*rect.inflate(1))

                    if self.color_scheme:
                        rgba = self.color_scheme.get_layer_fill_rgba(layer_index)
                    else:
                        rgba = [0.5, 0.5, 0.5, 0.9]
                    context.set_source_rgba(*rgba)

                    context.fill()

                    self.draw_dish_key_background(context, 1.0, item.layer_id)

            # draw key
            if item.is_key() and \
               clip_rect.intersects(item.get_canvas_rect()):
                item.draw(context)
                item.draw_image(context)
                item.draw_label(context)

        # draw touch handles (enlarged move and resize handles)
        if self.touch_handles.active:
            corner_radius = config.CORNER_RADIUS if decorated else 0
            self.touch_handles.set_corner_radius(corner_radius)
            self.touch_handles.draw(context)
예제 #32
0
    def reposition(self, x, y):
        """
        Move the window from a transition, not meant for user positioning.
        """
        # remember rects to distimguish from user move/resize
        w, h = self.get_size()
        self.remember_rect(Rect(x, y, w, h))

        self.move(x, y)
예제 #33
0
    def test_valid_test_environment(self):
        # write to dconf database to make sure it exists
        self._gsettings_set("org.onboard", "use-system-defaults", True)
        self.assertEqual(
            self._gsettings_get("org.onboard", "use-system-defaults"), True)
        self.assertTrue(os.path.exists(self._dconf_db_fn))

        # database must be reset to defaults
        self.assertEqual(str(self._get_window_rect()),
                         str(Rect(100, 50, 700, 205)))
예제 #34
0
    def draw_window_frame(self, context, lod):
        corner_radius = config.CORNER_RADIUS
        border_rgba = self.get_popup_window_rgba("border")
        alpha = border_rgba[3]

        colors = [
            [[0.5, 0.5, 0.5, alpha], 0, 1],
            [border_rgba, 1.5, 2.0],
        ]

        rect = Rect(0, 0, self.get_allocated_width(),
                    self.get_allocated_height())

        for rgba, pos, width in colors:
            r = rect.deflate(width)
            roundrect_arc(context, r, corner_radius)
            context.set_line_width(width)
            context.set_source_rgba(*rgba)
            context.stroke()
예제 #35
0
    def draw_window_frame(self, context, lod):
        corner_radius = config.CORNER_RADIUS
        border_rgba = self.get_popup_window_rgba("border")
        alpha = border_rgba[3]

        colors = [
                  [[0.5, 0.5, 0.5, alpha], 0  , 1],
                  [border_rgba,            1.5, 2.0],
                 ]

        rect = Rect(0, 0, self.get_allocated_width(),
                          self.get_allocated_height())

        for rgba, pos, width in colors:
            r = rect.deflate(width)
            roundrect_arc(context, r, corner_radius)
            context.set_line_width(width)
            context.set_source_rgba(*rgba)
            context.stroke()
예제 #36
0
    def get_damage_rect(self, context):
        clip_rect = Rect.from_extents(*context.clip_extents())

        # Draw a little more than just the clip_rect.
        # Prevents glitches around pressed keys in at least classic theme.
        layout = self.get_layout()
        if layout:
            extra_size = layout.context.scale_log_to_canvas((2.0, 2.0))
        else:
            extra_size = 0, 0
        return clip_rect.inflate(*extra_size)
예제 #37
0
    def get_damage_rect(self, context):
        clip_rect = Rect.from_extents(*context.clip_extents())

        # Draw a little more than just the clip_rect.
        # Prevents glitches around pressed keys in at least classic theme.
        layout = self.get_layout()
        if layout:
            extra_size = layout.context.scale_log_to_canvas((2.0, 2.0))
        else:
            extra_size = 0, 0
        return clip_rect.inflate(*extra_size)
예제 #38
0
 def update_window_rect(self):
     """
     Call this on configure event, the only time when
     get_position, get_size, etc. can be trusted.
     """
     visible = self.is_visible()
     if visible:
         self._window_rect = Rect.from_position_size(Gtk.Window.get_position(self),
                                                     Gtk.Window.get_size(self))
         self._origin      = self.get_window().get_origin()
         self._screen_orientation = self.get_screen_orientation()
예제 #39
0
    def _calc_bounds(self):
        """ Calculate the bounding rectangle over all items of this panel """
        # If there is no visible item return an empty rect
        if all(not item.is_visible() for item in self.items):
            return Rect()

        compact = self.compact
        bounds = None
        for item in self.items:
            if not compact or item.visible:
                rect = item.get_border_rect()
                if not rect.is_empty():
                    if bounds is None:
                        bounds = rect
                    else:
                        bounds = bounds.union(rect)

        if bounds is None:
            return Rect()
        return bounds
예제 #40
0
 def read_window_rect(self, orientation):
     """
     Read orientation dependent rect.
     Overload for WindowRectPersist.
     """
     if orientation == Orientation.LANDSCAPE:
         co = config.icp.landscape
     else:
         co = config.icp.portrait
     rect = Rect(co.x, co.y, max(co.width, 10), max(co.height, 10))
     return rect
예제 #41
0
    def position_at(self, x, y, x_align, y_align):
        """
        Align the window with the given point.
        x, y in root window coordinates.
        """
        rect = Rect.from_position_size(self.get_position(), self.get_size())
        rect = rect.align_at_point(x, y, x_align, y_align)
        rect = self.limit_to_workarea(rect)
        x, y = rect.get_position()

        self.move(x, y)
예제 #42
0
 def get_accessible_extents(accessible):
     """ Screen rect of the given accessible, no caching """
     try:
         rect = AtspiStateTracker._get_accessible_extents(accessible)
     # private exception gi._glib.GError when
     # right clicking onboards unity2d launcher (Precise)
     except Exception as ex:
         _logger.atspi("Invalid accessible,"
                       " failed to get extents: " + unicode_str(ex))
         rect = Rect()
     return rect
예제 #43
0
 def read_window_rect(self, orientation):
     """
     Read orientation dependent rect.
     Overload for WindowRectTracker.
     """
     if orientation == Orientation.LANDSCAPE:
         co = config.window.landscape
     else:
         co = config.window.portrait
     rect = Rect(co.x, co.y, co.width, co.height)
     return rect
예제 #44
0
    def position_at(self, x, y, x_align, y_align):
        """
        Align the window with the given point.
        x, y in root window coordinates.
        """
        rect = Rect.from_position_size(self.get_position(), self.get_size())
        rect = rect.align_at_point(x, y, x_align, y_align)
        rect = self.limit_to_workarea(rect)
        x, y = rect.get_position()

        self.move(x, y)
예제 #45
0
    def _clear_xembed_background(self, context):
        """ fill with plain layer 0 color; no alpha support required """
        rect = Rect(0, 0, self.get_allocated_width(),
                          self.get_allocated_height())

        # draw background image
        if config.get_xembed_background_image_enabled():
            pixbuf = self._get_xembed_background_image()
            if pixbuf:
                src_size = (pixbuf.get_width(), pixbuf.get_height())
                x, y = 0, rect.bottom() - src_size[1]
                Gdk.cairo_set_source_pixbuf(context, pixbuf, x, y)
                context.paint()

        # draw solid colored bar on top (with transparency, usually)
        rgba = config.get_xembed_background_rgba()
        if rgba is None:
            rgba = self.get_background_rgba()
            rgba[3] = 0.5
        context.set_source_rgba(*rgba)
        context.rectangle(*rect)
        context.fill()
예제 #46
0
    def get_repositioned_window_rect(self, home):
        """
        Get the alternative window rect suggested by auto-show or None if
        no repositioning is required.
        """
        accessible = self._focused_accessible
        if accessible:

            try:
                ext = accessible.get_extents(Atspi.CoordType.SCREEN)
            except: # private exception gi._glib.GError when
                    # right clicking onboards unity2d launcher (Precise)
                _logger.info("AtspiAutoHide: Invalid accessible,"
                             " failed to get extents")
                return None

            rect = Rect(ext.x, ext.y, ext.width, ext.height)

            if not rect.is_empty() and \
               not self._lock_visible:

                return self._get_window_rect_for_accessible_rect(home, rect)

        return None
예제 #47
0
    def draw(self, context):
        if self.opacity:
            clip_rect = Rect.from_extents(*context.clip_extents())
            for handle in self.handles:
                rect = handle.get_shadow_rect()
                if rect.intersects(clip_rect):
                    context.save()
                    context.rectangle(*rect.int())
                    context.clip()
                    context.push_group()

                    handle.draw(context)

                    context.pop_group_to_source()
                    context.paint_with_alpha(self.opacity);
                    context.restore()
예제 #48
0
    def get_dock_rect(self):
        area, geom = self.get_docking_monitor_rects()
        edge = config.window.docking_edge

        width, height = self.get_dock_size()
        rect = Rect(area.x, 0, area.w, height)
        if edge: # Bottom
            rect.y = area.y + area.h - height
        else:    # Top
            rect.y = area.y

        expand = self.get_dock_expand()
        if expand:
            rect.w = area.w
            rect.x = area.x
        else:
            rect.w = min(width, area.w)
            rect.x = rect.x + (area.w - rect.w) // 2
        return rect
예제 #49
0
 def get_display_limits(self):
     rootwin = Gdk.get_default_root_window()
     return Rect.from_position_size(rootwin.get_position(),
                             (rootwin.get_width(), rootwin.get_height()))
예제 #50
0
    def _on_draw(self, widget, cr):
        """
        Draw the onboard icon.
        """
        if not Gtk.cairo_should_draw_window(cr, self.get_window()):
            return False

        width = float(self.get_allocated_width())
        height = float(self.get_allocated_height())

        # draw themed icon

        keys = [RectKey("icon" + str(i)) for i in range(4)]
        color_scheme = self.get_color_scheme()

        # Default colors for the case when none of the icon keys
        # are defined in the color scheme.
        background_rgba =  [1.0, 1.0, 1.0, 1.0]
        fill_rgbas      = [[0.9, 0.7, 0.0, 0.75],
                           [1.0, 1.0, 1.0, 1.0],
                           [1.0, 1.0, 1.0, 1.0],
                           [0.0, 0.54, 1.0, 1.0]]
        stroke_rgba     =  [0.0, 0.0, 0.0, 1.0]
        label_rgba      =  [0.0, 0.0, 0.0, 1.0]

        themed = False
        if color_scheme:
            if any(color_scheme.is_key_in_schema(key) for key in keys):
                themed = True

        # clear background
        cr.save()
        cr.set_operator(cairo.OPERATOR_CLEAR)
        cr.paint()
        cr.restore()

        # draw background color
        background_rgba = list(color_scheme.get_icon_rgba("background"))

        if Gdk.Screen.get_default().is_composited():
            background_rgba[3] *= 0.75
            cr.set_source_rgba(*background_rgba)

            rect = Rect(0, 0, width, height)
            corner_radius = min(width, height) * 0.1

            roundrect_arc(cr, rect, corner_radius)
            cr.fill()

            # decoration frame
            line_rect = rect.deflate(2)
            cr.set_line_width(2)
            roundrect_arc(cr, line_rect, corner_radius)
            cr.stroke()
        else:
            cr.set_source_rgba(*background_rgba)
            cr.paint()

        # four rounded rectangles
        rects = Rect(0.0, 0.0, 100.0, 100.0).deflate(5) \
                                            .subdivide(2, 2, 6)
        cr.save()
        cr.scale(width / 100., height / 100.0)
        cr.select_font_face ("sans-serif")
        cr.set_line_width(2)

        for i, key in enumerate(keys):
            rect = rects[i]

            if themed:
                fill_rgba   = color_scheme.get_key_rgba(key, "fill")
                stroke_rgba  = color_scheme.get_key_rgba(key, "stroke")
                label_rgba   = color_scheme.get_key_rgba(key, "label")
            else:
                fill_rgba   = fill_rgbas[i]

            roundrect_arc(cr, rect, 5)
            cr.set_source_rgba(*fill_rgba)
            cr.fill_preserve()

            cr.set_source_rgba(*stroke_rgba)
            cr.stroke()

            if i == 0 or i == 3:
                if i == 0:
                    letter = "O"
                else:
                    letter = "B"

                cr.set_font_size(25)
                x_bearing, y_bearing, _width, _height, \
                x_advance, y_advance = cr.text_extents(letter)
                r = rect.align_rect(Rect(0, 0, _width, _height),
                                         0.3, 0.33)
                cr.move_to(r.x - x_bearing, r.y - y_bearing)
                cr.set_source_rgba(*label_rgba)
                cr.show_text(letter)
                cr.new_path()

        cr.restore()

        return True
예제 #51
0
    def _parse_legacy_layout(self, dom_node):

        # parse panes
        panes = []
        is_scan = False
        for i, pane_node in enumerate(dom_node.getElementsByTagName("pane")):
            item = LayoutPanel()
            item.layer_id = "layer {}".format(i)

            item.id       = pane_node.attributes["id"].value
            item.filename = pane_node.attributes["filename"].value

            # parse keys
            keys = []
            for node in pane_node.getElementsByTagName("key"):
                key = self._parse_key(node, item)                
                if key:
                    # some keys have changed since Onboard 0.95
                    if key.id == "middleClick":
                        key.set_id("middleclick")
                        key.action_type = KeyCommon.BUTTON_ACTION
                    if key.id == "secondaryClick":
                        key.set_id("secondaryclick")
                        key.action_type = KeyCommon.BUTTON_ACTION
                        
                    keys.append(key)
                    
            item.set_items(keys)

            # check for scan columns
            if pane_node.getElementsByTagName("column"):
                is_scan = True

            panes.append(item)

        layer_area = LayoutPanel()
        layer_area.id = "layer_area"
        layer_area.set_items(panes)

        # find the most frequent key width
        histogram = {}
        for key in layer_area.iter_keys():
            w = key.get_border_rect().w
            histogram[w] = histogram.get(w, 0) + 1
        most_frequent_width = max(list(zip(list(histogram.values()), list(histogram.keys()))))[1] \
                              if histogram else 18

        # Legacy onboard had automatic tab-keys for pane switching.
        # Simulate this by generating layer buttons from scratch.
        keys = []
        group = "__layer_buttons__"
        widen = 1.4 if not is_scan else 1.0
        rect = Rect(0, 0, most_frequent_width * widen, 20)

        key = RectKey()
        attributes = {}
        attributes["id"]     = "hide"
        attributes["group"]  = group
        attributes["image"]  = "close.svg"
        attributes["button"] = "true"
        attributes["scannable"] = "false"
        self._init_key(key, attributes)
        key.set_border_rect(rect.copy())
        keys.append(key)

        key = RectKey()
        attributes = {}
        attributes["id"]     = "move"
        attributes["group"]  = group
        attributes["image"]  = "move.svg"
        attributes["button"] = "true"
        attributes["scannable"] = "false"
        self._init_key(key, attributes)
        key.set_border_rect(rect.copy())
        keys.append(key)

        if len(panes) > 1:
            for i, pane in enumerate(panes):
                key = RectKey()
                attributes = {}
                attributes["id"]     = "layer{}".format(i)
                attributes["group"]  = group
                attributes["label"]  = pane.id
                attributes["button"] = "true"
                self._init_key(key, attributes)
                key.set_border_rect(rect.copy())
                keys.append(key)

        layer_switch_column = LayoutBox()
        layer_switch_column.horizontal = False
        layer_switch_column.set_items(keys)

        layout = LayoutBox()
        layout.border = 1
        layout.spacing = 2
        layout.set_items([layer_area, layer_switch_column])

        return [layout]
예제 #52
0
 def get_rootwin_rect():
     rootwin = Gdk.get_default_root_window()
     return Rect.from_position_size(rootwin.get_position(),
                             (rootwin.get_width(), rootwin.get_height()))