Example #1
0
def readBool(text):
    reply = wireutils.color_input(text + ' (y/n): ')

    if reply == 'y':
        return True
    elif reply == 'n':
        return False
    else:
        print
        wireutils.color_print("Invalid option. Please answer y or n for yes or no.\n", color = wireutils.ansi_colors.RED)

    return readBool(text)
Example #2
0
def checkModule(name):
    installed = hasModule(name)
    if installed:
        if not args.get("quiet") and args.get("clean"):
            print wireutils.format("m {name}: y", name = name)
        elif not args.get("quiet"):
            wireutils.color_print("Module {name} installed.", name = name, color = wireutils.ansi_colors.GREEN)
    else:
        if args.get("clean"):
            print wireutils.format("m {name}: n", name = name)
        else:
            wireutils.color_print("Module {name} not installed.", name = name, color = wireutils.ansi_colors.RED)

    return installed
Example #3
0
def checkApplication(name, friendlyName, tutorial):
    installed = spawn.find_executable(name) != None
    if installed:
        if not args.get("quiet") and args.get("clean"):
            print wireutils.format("a {name}: y", name = name)
        elif not args.get("quiet"):
            wireutils.color_print("Executable {name} ({readable}) found.", name = name, readable = friendlyName, color=wireutils.ansi_colors.GREEN)
    else:
        if args.get("clean"):
            print wireutils.format("a {name}: n", name = name)
        else:
            wireutils.color_print("Executable {name} ({readable}) not found.", name = name, readable = friendlyName, color=wireutils.ansi_colors.RED)

    if not installed and not args.get("dry"):
        manualInstallNotify(friendlyName, tutorial)
Example #4
0
ICON = os.path.join(dirname, os.path.pardir, "icon_glow.png")
LOGO = os.path.join(dirname, os.path.pardir, "icon_plain.png")
VERSION = 'Perdyshot ' + open(os.path.join(dirname, os.path.pardir, '.version'), 'r').read()
URL = "https://github.com/Locercus/Perdyshot"

DATE = os.path.getmtime(os.path.join(dirname, os.path.pardir, ".version"))
DATE = datetime.fromtimestamp(DATE).strftime(locale.nl_langinfo(locale.D_T_FMT))

if Notify:
    Notify.init("Perdyshot")


config = ConfigObj(os.path.join(dirname, os.path.pardir, 'perdyshot.conf'), encoding = 'UTF8', configspec = os.path.join(dirname, os.path.pardir, 'perdyshot.conf.spec'))
validator = Validator()
if not config.validate(validator):
    wireutils.color_print("Invalid configuration file", color = wireutils.ansi_colors.DARKRED)
    sys.exit(1)

settings = {}

settings['modes'] = config['GUI']['CaptureModes']


app = QtGui.QApplication(sys.argv)

# Create about dialog
class AboutDialog(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setFixedSize(450, 240)
        self.setWindowTitle("About Perdyshot")
Example #5
0
def main(argSource):
    cwd = os.getcwd()

    app = QtGui.QApplication(sys.argv)


    version = 'Perdyshot ' + open(os.path.join(dirname, os.path.pardir, '.version'), 'r').read()

    parser = argparse.ArgumentParser(description = 'Takes a perdy screenshot of an area selection.')

    parser.add_argument('-f', '--file', help = 'overrides setting in perdyshot.conf', default = None)

    parser.add_argument('-v', '--version', action = 'version', version = version)

    args = vars(parser.parse_args(argSource))

    config = ConfigObj(os.path.join(dirname, os.path.pardir, 'perdyshot.conf'), encoding = 'UTF8', configspec = os.path.join(dirname, os.path.pardir, 'perdyshot.conf.spec'))
    validator = Validator()
    if not config.validate(validator):
        wireutils.color_print("Invalid configuration file", color = wireutils.ansi_colors.DARKRED)
        sys.exit(1)


    settings = {}

    settings['filename'] = config['Settings']['filename']

    PressMode = Enum('PressMode', 'Dragging KeyDragging CreateResizeCenter Creating ResizeLeft ResizeTop ResizeRight ResizeBottom ResizeTopLeft ResizeTopRight ResizeBottomRight ResizeBottomLeft')


    # Create area screenshot selection window
    class AreaWindow(QtGui.QWidget):
        def __init__(self, width, height):
            QtGui.QWidget.__init__(self)

            self.setContentsMargins(-1, -1, -1, -1) # Hacky af but it works

            self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)

            self.setCursor(Qt.CrossCursor)

            self.scene = QtGui.QGraphicsScene()

            self.view = QtGui.QGraphicsView(self.scene)
            self.view.setFocusPolicy(Qt.NoFocus)
            self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
            self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

            self.view.setMouseTracking(True)
            self.view.mouseMoveEvent = self.mouseMoveEvent
            self.view.mousePressEvent = self.mousePressEvent
            self.view.mouseReleaseEvent = self.mouseReleaseEvent

            self.layout = QtGui.QVBoxLayout()
            self.layout.setContentsMargins(0, 0, 0, 0)
            self.layout.addWidget(self.view)
            self.setLayout(self.layout)

            self.background = QtGui.QGraphicsPixmapItem(QtGui.QPixmap(os.path.join(tempfile.gettempdir(), 'perdyselection.png')))
            self.scene.addItem(self.background)

            coverBrush = QtGui.QBrush(QtGui.QColor(0, 0, 0, 128))
            coverPen = QtGui.QPen(QtGui.QColor(0, 0, 0, 0))

            self.coverLeft = QtGui.QGraphicsRectItem(0, 0, width, height)
            self.coverLeft.setBrush(coverBrush)
            self.coverLeft.setPen(coverPen)
            self.scene.addItem(self.coverLeft)

            self.coverRight = QtGui.QGraphicsRectItem(0, 0, 0, 0)
            self.coverRight.setBrush(coverBrush)
            self.coverRight.setPen(coverPen)
            self.scene.addItem(self.coverRight)

            self.coverTop = QtGui.QGraphicsRectItem(0, 0, 0, 0)
            self.coverTop.setBrush(coverBrush)
            self.coverTop.setPen(coverPen)
            self.scene.addItem(self.coverTop)

            self.coverBottom = QtGui.QGraphicsRectItem(0, 0, 0, 0)
            self.coverBottom.setBrush(coverBrush)
            self.coverBottom.setPen(coverPen)
            self.scene.addItem(self.coverBottom)

            self.selection = QtGui.QGraphicsRectItem(0, 0, 0, 0)
            selectionPen = QtGui.QPen(QtGui.QColor(0xffffff))
            selectionPen.setStyle(Qt.DashLine)
            self.selection.setPen(selectionPen)
            self.scene.addItem(self.selection)

            self.leftPressed = False
            self.pressMode = None
            self.selPos =  (0, 0, 0, 0)
            self.selDims = (0, 0, 0, 0)
            self.curPos =  (0, 0)

        def mousePressEvent(self, event):
            x, y = event.x(), event.y()
            dx, dy, dw, dh = self.selDims

            button = event.button()

            if button == Qt.LeftButton:
                self.leftPressed = True

                self.pressMode = self.getPositionPressMode(x, y)

                if self.pressMode == PressMode.Creating:
                    self.selPos = (x, y, 0, 0)
                    self.selDims = (0, 0, 0, 0)

                    self.selection.setRect(x, y, 0, 0)
                    self.coverLeft.setRect(0, 0, self.width(), self.height())
                    self.coverRight.setRect(0, 0, 0, 0)
                    self.coverTop.setRect(0, 0, 0, 0)
                    self.coverBottom.setRect(0, 0, 0, 0)

            elif button == Qt.RightButton:
                self.pressMode = None

                self.selPos = (0, 0, 0, 0)
                self.selDims = (0, 0, 0, 0)

                self.selection.setRect(0, 0, 0, 0)
                self.coverLeft.setRect(0, 0, self.width(), self.height())
                self.coverRight.setRect(0, 0, 0, 0)
                self.coverTop.setRect(0, 0, 0, 0)
                self.coverBottom.setRect(0, 0, 0, 0)

            self.updateCursor()

        def mouseReleaseEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.leftPressed = False
                self.pressMode = None

                # Fix mirrored selections
                self.selPos = self.selDims

            self.updateCursor()

        def mouseMoveEvent(self, event):
            if self.leftPressed:
                tw, th = self.width(), self.height()
                x, y, w, h = self.selPos
                dx, dy, dw, dh = self.selDims
                mx, my = event.x(), event.y()
                mxo, myo = self.curPos
                xDiff = mx - mxo
                yDiff = my - myo

                if self.pressMode in [PressMode.Dragging, PressMode.KeyDragging]:
                    x += xDiff
                    y += yDiff

                elif self.pressMode == PressMode.CreateResizeCenter:
                    x -= xDiff
                    y -= yDiff
                    w += xDiff * 2
                    h += yDiff * 2

                elif self.pressMode == PressMode.Creating:
                    w = event.x() - x
                    h = event.y() - y

                elif self.pressMode == PressMode.ResizeLeft:
                    x += xDiff
                    w -= xDiff

                elif self.pressMode == PressMode.ResizeTop:
                    y += yDiff
                    h -= yDiff

                elif self.pressMode == PressMode.ResizeRight:
                    w += xDiff

                elif self.pressMode == PressMode.ResizeBottom:
                    h += yDiff

                elif self.pressMode == PressMode.ResizeTopLeft:
                    x += xDiff
                    y += yDiff
                    w -= xDiff
                    h -= yDiff

                elif self.pressMode == PressMode.ResizeTopRight:
                    w += xDiff
                    y += yDiff
                    h -= yDiff

                elif self.pressMode == PressMode.ResizeBottomRight:
                    w += xDiff
                    h += yDiff

                elif self.pressMode == PressMode.ResizeBottomLeft:
                    x += xDiff
                    w -= xDiff
                    h += yDiff




                self.selPos = (x, y, w, h)

                if w < 0:
                    x, w = x + w, -w

                if h < 0:
                    y, h = y + h, -h

                self.selDims = (x, y, w, h)

                self.selection.setRect(x, y, w, h)
                self.coverLeft.setRect(0, 0, x, th)
                self.coverRight.setRect(x + w, 0, tw, th)
                self.coverTop.setRect(x, 0, w, y)
                self.coverBottom.setRect(x, y + h, w, th - y - h)

            self.curPos = (event.x(), event.y())
            self.updateCursor()


        def keyPressEvent(self, event):
            key = event.key()

            tw, th = self.width(), self.height()
            x, y, w, h = self.selPos
            dx, dy, dw, dh = self.selDims

            if key == Qt.Key_Escape:
                if __name__ == '__main__':
                    sys.exit()
                else:
                    self.hide()

            elif key in [Qt.Key_Enter, Qt.Key_Return]:
                self.capture(dx, dy, dw, dh)

            elif key == Qt.Key_Space:
                if self.pressMode == PressMode.Creating:
                    self.pressMode = PressMode.KeyDragging

            elif key == Qt.Key_Alt:
                if self.pressMode == PressMode.Creating:
                    self.pressMode = PressMode.CreateResizeCenter

            elif key in [Qt.Key_Left, Qt.Key_Up, Qt.Key_Right, Qt.Key_Down]:
                if self.pressMode is None:
                    diffx = 0
                    diffy = 0

                    if key == Qt.Key_Left:
                        diffx = -1

                    elif key == Qt.Key_Up:
                        diffy = -1

                    elif key == Qt.Key_Right:
                        diffx = 1

                    elif key == Qt.Key_Down:
                        diffy = 1


                    if event.modifiers() & Qt.ShiftModifier:
                        diffx *= 4
                        diffy *= 4


                    x  += diffx
                    dx += diffx

                    y  += diffy
                    dy += diffy

                    self.selPos = (x, y, w, h)
                    self.selDims = (dx, dy, dw, dh)

                    self.selection.setRect(dx, dy, dw, dh)
                    self.coverLeft.setRect(0, 0, x, th)
                    self.coverRight.setRect(x + w, 0, tw, th)
                    self.coverTop.setRect(x, 0, w, y)
                    self.coverBottom.setRect(x, y + h, w, th - y - h)

            self.updateCursor()


        def keyReleaseEvent(self, event):
            key = event.key()

            if key == Qt.Key_Space:
                if self.pressMode == PressMode.KeyDragging:
                    self.pressMode = PressMode.Creating

            elif key == Qt.Key_Alt:
                if self.pressMode == PressMode.CreateResizeCenter:
                    self.pressMode = PressMode.Creating


        def getPositionPressMode(self, x, y):
            dx, dy, dw, dh = self.selDims

            if x in xrange(dx + 8, dx + dw - 8) and y in xrange(dy + 8, dy + dh - 8):
                return PressMode.Dragging

            elif x in xrange(dx - 8, dx + 8) and y in xrange(dy + 8, dy + dh - 8):
                return PressMode.ResizeLeft

            elif x in xrange(dx + 8, dx + dw - 8) and y in xrange(dy - 8, dy + 8):
                return PressMode.ResizeTop

            elif x in xrange(dx + dw - 8, dx + dw + 8) and y in xrange(dy + 8, dy + dh - 8):
                return PressMode.ResizeRight

            elif x in xrange(dx + 8, dx + dw - 8) and y in xrange(dy + dh - 8, dy + dh + 8):
                return PressMode.ResizeBottom

            elif x in xrange(dx - 8, dx + 8) and y in xrange(dy - 8, dy + 8):
                return PressMode.ResizeTopLeft

            elif x in xrange(dx + dw - 8, dx + dw + 8) and y in xrange(dy - 8, dy + 8):
                return PressMode.ResizeTopRight

            elif x in xrange(dx + dw - 8, dx + dw + 8) and y in xrange(dy + dh - 8, dy + dh + 8):
                return PressMode.ResizeBottomRight

            elif x in xrange(dx - 8, dx + 8) and y in xrange(dy + dh - 8, dy + dh + 8):
                return PressMode.ResizeBottomLeft

            else:
                return PressMode.Creating


        # Set the cursor according to its position
        def updateCursor(self):
            x, y = self.curPos

            rx, ry, rw, rh = self.selDims
            rx2, ry2 = rx + rw, ry + rh

            mode = self.getPositionPressMode(x, y)

            if self.pressMode == PressMode.KeyDragging:
                self.setCursor(Qt.ClosedHandCursor)

            elif self.pressMode == PressMode.CreateResizeCenter:
                self.setCursor(Qt.SizeAllCursor)

            elif self.pressMode == PressMode.Creating or mode == PressMode.Creating:
                self.setCursor(Qt.CrossCursor)

            elif mode == PressMode.Dragging:
                if self.leftPressed:
                    self.setCursor(Qt.ClosedHandCursor)
                else:
                    self.setCursor(Qt.OpenHandCursor)

            elif mode in [PressMode.ResizeLeft, PressMode.ResizeRight]:
                self.setCursor(Qt.SizeHorCursor)

            elif mode in [PressMode.ResizeTop, PressMode.ResizeBottom]:
                self.setCursor(Qt.SizeVerCursor)

            elif mode in [PressMode.ResizeBottomLeft, PressMode.ResizeTopRight]:
                self.setCursor(Qt.SizeBDiagCursor)

            elif mode in [PressMode.ResizeTopLeft, PressMode.ResizeBottomRight]:
                self.setCursor(Qt.SizeFDiagCursor)


        # Captures the screenshot
        def capture(self, x, y, w, h):
            self.hide()

            filename = args['file'] if args['file'] != None else settings['filename']
            filename = time.strftime(filename)

            image = Image.open(os.path.join(tempfile.gettempdir(), 'perdyselection.png'))
            image = image.crop((x, y, x + w, y + h))
            image.save(filename, 'png')

            if __name__ == '__main__':
                sys.exit()




    areaWindow = None

    def activate():
        screen = gdk.screen_get_default()

        screenWidth  = screen.get_width()
        screenHeight = screen.get_height()

        pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, True, 8, screenWidth, screenHeight)
        screenshot = gdk.Pixbuf.get_from_drawable(pixbuf, gdk.get_default_root_window(), gdk.colormap_get_system(), 0, 0, 0, 0, screenWidth, screenHeight)
        screenshot.save(os.path.join(tempfile.gettempdir(), 'perdyselection.png'), 'png')

        areaWindow = AreaWindow(screenWidth, screenHeight)
        areaWindow.move(0, 0)
        areaWindow.setFixedSize(screenWidth, screenHeight)
        areaWindow.show()

    if __name__ == '__main__':
        activate()

    app.exec_()
Example #6
0


if __name__ == "__main__":
    try:
        try:
            import argparse
            parser = argparse.ArgumentParser(description = 'Checks the Perdyshot dependencies.', usage="%(prog)s [options]")
            parser.add_argument('-o', '--omit', help="Omit an update step", default="", choices=["module", "app", "m", "a"], dest="omit")
            parser.add_argument('--dry-run', help="Don't actually do anything", action = 'store_true', dest="dry")
            parser.add_argument('-q', '--quiet', help="Supress most output", action = 'store_true', dest="quiet")
            parser.add_argument('--porcelain', help="Machine-readable output (implies --dry-run)", action = 'store_true', dest="clean")

            args = vars(parser.parse_args())
        except Exception:
            wireutils.color_print("Argparse library missing. Will not be able to parse cli arguments.\n", color=wireutils.ansi_colors.DARKRED)
            args = {}

        if not args.get("quiet") and not args.get("clean"):
            wireutils.color_print("""Perdyshot Dependency Checker
                          {bold}============================{endc}
                                """,
                                strip = True)

        ROOT = os.geteuid() == 0

        if not args.get("dry") and not args.get("clean"):
            if not ROOT:
                if not readBool("You aren't root.\nInstalling missing packages will not be supported.\nDo you wish to continue?"):
                    sys.exit()
                print
Example #7
0
def main(argSource):
    cwd = os.getcwd()

    version = 'Perdyshot ' + open(os.path.join(dirname, os.path.pardir, '.version'), 'r').read()

    parser = argparse.ArgumentParser(description = 'Takes a perdy screenshot of the active window.')

    parser.add_argument('-b', '--background', help = 'overrides setting in perdyshot.conf', default = '')

    parser.add_argument('--delay', help = 'the delay in seconds before capturing the active window (default: 1)', default = 1, type = float)

    parser.add_argument('-f', '--file', help = 'overrides setting in perdyshot.conf', default = None)

    parser.add_argument('--round-top', help = "overrides setting in perdyshot.conf", default = None, action = 'store_true')
    parser.add_argument('--no-round-top', help = "overrides setting in perdyshot.conf", dest = 'round_top', action = 'store_false')

    parser.add_argument('--round-bottom', help = "overrides setting in perdyshot.conf", type = int, choices = [0, 1, 2], default = None)

    parser.add_argument('--shadow', help = "overrides setting in perdyshot.conf", default = None)

    parser.add_argument('--size-bugged', help = "overrides setting in perdyshot.conf", type = int, default = None, choices = [0, 1, 2])

    parser.add_argument('-v', '--version', action = 'version', version = version)

    args = vars(parser.parse_args(argSource))

    config = ConfigObj(os.path.join(dirname, os.path.pardir, 'perdyshot.conf'), encoding = 'UTF8', configspec = os.path.join(dirname, os.path.pardir, 'perdyshot.conf.spec'))
    validator = Validator()
    if not config.validate(validator):
        wireutils.color_print("Invalid configuration file", color = wireutils.ansi_colors.DARKRED)
        sys.exit(1)



    wireutils.color_print("Please select the window to be captured\n")
    time.sleep(args['delay'])

    startTime = time.time()

    # https://gist.github.com/mozbugbox/10cd35b2872628246140
    def pixbuf2image(pix):
        """Convert gdkpixbuf to PIL image"""
        data = pix.get_pixels()
        w = pix.props.width
        h = pix.props.height
        stride = pix.props.rowstride
        mode = "RGB"
        if pix.props.has_alpha == True:
            mode = "RGBA"
        im = Image.frombytes(mode, (w, h), data, "raw", mode, stride)
        return im

    # Get the root window
    root = gdk.screen_get_default()

    # And its size
    screenSize = (root.get_width(), root.get_height())

    # Get the active window
    window = root.get_active_window()

    if window == None:
        wireutils.color_print("Failed to capture window, exiting.", color = wireutils.ansi_colors.DARKRED)
        sys.exit(1)

    # And its geometry
    x, y = window.get_origin()
    x -= 1
    y -= 1
    width, height = window.get_size()

    # Fix something that may just be specific to my f****d up left monitor
    if x < 0:
        x = 0
        window.move(x, y)
        time.sleep(.5)

    # Get the position of the window decorations
    decoX, decoY = window.get_root_origin()
    decoY += 1

    # Check if the window has a custom titlebar
    hascustomtitlebar = (y + 2 == decoY)

    # Add the dimensions of the decorations to window dimensions
    width  += x - decoX + 1
    height += y - decoY - 1

    windowType = window.get_type_hint()

    # Get its WM_CLASS
    WM_CLASS = window.property_get('WM_CLASS')[2].split('\x00')[0]

    # Read the config file and figure out the settings
    settings = {}

    if config['Settings']['background'] == "False":
        settings['background'] = False
    else:
        settings['background'] = config['Settings']['background']

    settings['shadow'] = config['Settings']['shadowColour']

    settings['filename'] = config['Settings']['filename']

    if config['Settings']['cornerImage'] == '':
        settings['cornerImage'] = None
    else:
        settings['cornerImage'] = Image.open(os.path.join(dirname, config['Settings']['cornerImage']))

    if config['Settings']['cornerImageDM'] == '':
        settings['cornerImageDM'] = None
    else:
        settings['cornerImageDM'] = Image.open(os.path.join(dirname, config['Settings']['cornerImageDM']))

    if config['Settings']['borderImage'] == '':
        settings['borderImage'] = None
    else:
        settings['borderImage'] = Image.open(os.path.join(dirname, config['Settings']['borderImage']))

    if config['Settings']['borderImageDM'] == '':
        settings['borderImageDM'] = None
    else:
        settings['borderImageDM'] = Image.open(os.path.join(dirname, config['Settings']['borderImageDM']))


    if WM_CLASS in config['Applications']:
        app = config['Applications'][WM_CLASS]

        settings['sizeBugged'] = app['sizeBugged']

        settings['roundTop'] = app['roundTop']
        if settings['roundTop'] == None:
            settings['roundTop'] = not hascustomtitlebar

        settings['roundBottom'] = app['roundBottom']
        if settings['roundBottom'] == None:
            if hascustomtitlebar:
                settings['roundBottom'] = 0
            else:
                settings['roundBottom'] = 2
    else:
        settings['sizeBugged'] = False

        settings['roundTop'] = not hascustomtitlebar

        if hascustomtitlebar:
            settings['roundBottom'] = 0
        else:
            settings['roundBottom'] = 2

    # Add the border size
    width  += settings['borderImage'].size[0]
    height += settings['borderImage'].size[1]

    # Get pixbuf
    pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, True, 8, width, height)

    # Screenshot the window (and its decorations)
    screenshot = gdk.Pixbuf.get_from_drawable(pixbuf, gdk.get_default_root_window(), gdk.colormap_get_system(), decoX, decoY, 0, 0, width, height)

    # Convert it to a PIL image
    image = pixbuf2image(screenshot)

    # Find out how long it took
    partialTime = time.time()

    # Get the geometry of the window's monitor
    monitorid = root.get_monitor_at_window(window)
    monitor = root.get_monitor_geometry(monitorid)

    geometry = window.get_geometry()
    bounds = window.get_frame_extents()


    # This is an estimate by a long-shot, but it's usually about right
    # At least on Pantheon, the gtk.gdk.WINDOW_STATE_MAXIMIZED state isn't set, so we resort to this
    maximized = height + 31 >= monitor.height and bounds.y - monitor.y + bounds.height == monitor.height

    sizeBugged = args['size_bugged'] if args['size_bugged'] != None else settings['sizeBugged']
    if sizeBugged == 1 or (sizeBugged == 2 and not(windowType & gdk.WINDOW_TYPE_HINT_DIALOG)):
        if not maximized:
            if windowType & gdk.WINDOW_TYPE_HINT_DIALOG:
                image = image.crop((37, 27, width - 38, height - 48))
                width -= 38 + 37
                height -= 48 + 27
            else:
                image = image.crop((50, 38, width - 51, height - 62))
                width -= 51 + 50
                height -= 62 + 38

    # Fix borders
    pixels = image.load()

    roundTop = args['round_top'] if args['round_top'] != None else settings['roundTop']

    roundBottom = args['round_bottom'] if args['round_bottom'] != None else settings['roundBottom']
    roundBottom = (roundBottom == 1 or (roundBottom == 2 and (maximized or windowType & gdk.WINDOW_TYPE_HINT_DIALOG)))

    # Apply deletion maps
    cornerDeleteMapSize = (0, 0)
    if settings['cornerImageDM'] != None:
        cornerDeleteMap = settings['cornerImageDM'].load()
        cornerDeleteMapSize = settings['cornerImageDM'].size
        for deleteColumn in xrange(0, cornerDeleteMapSize[0]):
            for deleteRow in xrange(0, cornerDeleteMapSize[1]):
                if cornerDeleteMap[deleteColumn, deleteRow][3] > 0:
                    if roundTop:
                        # Top left
                        pixels[deleteColumn, deleteRow] = (0, 0, 0, 0)
                        # Top right
                        pixels[width - deleteColumn - 1, deleteRow] = (0, 0, 0, 0)
                    if roundBottom:
                        # Bottom left
                        pixels[deleteColumn, height - deleteRow - 1] = (0, 0, 0, 0)
                        # Bottom right
                        pixels[width - deleteColumn - 1, height - deleteRow - 1] = (0, 0, 0, 0)

        if settings['borderImageDM'] != None:
            borderDeleteMap = settings['borderImageDM'].load()
            borderDeleteMapSize = settings['borderImageDM'].size
            for imx in xrange(0, width, borderDeleteMapSize[0]):
                for deleteColumn in xrange(0, borderDeleteMapSize[0]):
                    for deleteRow in xrange(0, borderDeleteMapSize[1]):
                        if borderDeleteMap[deleteColumn, deleteRow][3] > 0:
                            # Top
                            if not (roundTop and imx in xrange(cornerDeleteMapSize[0] - 1, width - cornerDeleteMapSize[0] - 1)):
                                pixels[imx + deleteColumn, deleteRow] = (0, 0, 0, 0)
                            # Bottom
                            if not (roundBottom and imx in xrange(cornerDeleteMapSize[0] - 1, width - cornerDeleteMapSize[0] - 1)):
                                pixels[imx + deleteColumn, height - deleteRow - 1] = (0, 0, 0, 0)

            for imy in xrange(0, height, borderDeleteMapSize[1]):
                # TODO: Rotate the image
                for deleteColumn in xrange(0, borderDeleteMapSize[0]):
                    for deleteRow in xrange(0, borderDeleteMapSize[1]):
                        if borderDeleteMap[deleteColumn, deleteRow][3] > 0:
                            # Left
                            if not ((roundTop and imy < cornerDeleteMapSize[1] - 1) or (roundBottom and imy > height - cornerDeleteMapSize[1] - 1)):
                                pixels[deleteColumn, imy + deleteRow] = (0, 0, 0, 0)
                            # Right
                            if not ((roundTop and imy < cornerDeleteMapSize[1] - 1) or (roundBottom and imy > height - cornerDeleteMapSize[1] - 1)):
                                pixels[width - deleteColumn - 1, imy + deleteRow] = (0, 0, 0, 0)

    # Apply overlay images
    cornerImageSize = (0, 0)
    if settings['cornerImage'] != None:
        cornerImage = settings['cornerImage']
        cornerImageSize = cornerImage.size

        if roundTop:
            imageTopLeft = cornerImage.copy()
            image.paste(imageTopLeft, (0, 0), imageTopLeft)

            imageTopRight = ImageOps.mirror(cornerImage)
            image.paste(imageTopRight, (width - cornerImageSize[0], 0), imageTopRight)

        if roundBottom:
            imageBottomLeft = ImageOps.flip(cornerImage)
            image.paste(imageBottomLeft, (0, height - cornerImageSize[1]), imageBottomLeft)

            imageBottomRight = ImageOps.flip(ImageOps.mirror(cornerImage))
            image.paste(imageBottomRight, (width - cornerImageSize[0], height - cornerImageSize[1]), imageBottomRight)

    if settings['borderImage'] != None:
        borderImage = settings['borderImage']
        borderImageSize = borderImage.size

        for imx in xrange(1, width, borderImageSize[0]):
            # Top
            if not roundTop or imx in xrange(cornerImageSize[0], width - cornerImageSize[0]):
                borderImageCopy = borderImage.copy()
                image.paste(borderImageCopy, (imx, 0), borderImageCopy)

            # Bottom
            if not roundBottom or imx in xrange(cornerImageSize[0], width - cornerImageSize[0]):
                borderImageCopy = ImageOps.flip(borderImage)
                image.paste(borderImageCopy, (imx, height - 1), borderImageCopy)


        rangeStartY = 1
        if roundTop:
            rangeStartY = cornerImageSize[1] - 1

        rangeEndY = height - 1
        if roundBottom:
            rangeEndY = height - cornerImageSize[1]

        for imy in xrange(rangeStartY, rangeEndY, borderImageSize[0]):
            # Left
            borderImageCopy = borderImage.rotate(90)
            image.paste(borderImageCopy, (0, imy), borderImageCopy)

            # Right
            borderImageCopy = borderImage.rotate(270)
            image.paste(borderImageCopy, (width - 1, imy), borderImageCopy)



    # Save the image with PIL for modification with ImageMagick
    image.save(os.path.join(tempfile.gettempdir(), 'perdywindow.png'), 'png')

    # Apply a shadow
    shadowColour = args['shadow'] if args['shadow'] != None else settings['shadow']
    command  = "convert " + os.path.join(tempfile.gettempdir(), 'perdywindow.png') + " -bordercolor none -border 64x64 -repage +48+48 \( +clone -background \"" + shadowColour + "\" -shadow 100x24+0+32 \) +swap -background none -mosaic"

    # Change the background if necessary
    background = args['background'] if args['background'] != '' else settings['background']
    if background != '' and background != False:
        command += " -background \"" + background + "\" -alpha remove"

    # Apply our magick to our image and save it to a file
    filename = args['file'] if args['file'] != None else settings['filename']
    filename = time.strftime(filename)
    subprocess.check_output(command + " " + filename, shell = True)

    totalTime = time.time()
    print # An empty line.
    wireutils.color_print("Screenshot time: %.2f seconds" % (partialTime - startTime))
    wireutils.color_print("Post-processing time: %.2f seconds" % (totalTime - partialTime))
    wireutils.color_print("Total time: %.2f seconds" % (totalTime - startTime))
    print
    wireutils.color_print("Saved as {name}.", name = filename)