def __check_position(self): cursor_location = self.__moved_cursor_location or self.__cursor_location cursor_right = cursor_location[0] + cursor_location[2] cursor_bottom = cursor_location[1] + cursor_location[3] window_right = cursor_right + self.__toplevel.allocation.width window_bottom = cursor_bottom + self.__toplevel.allocation.height screen = gdk.screen_get_default() monitor_num = screen.get_monitor_at_point(cursor_location[0], cursor_location[1]) monitor_area = screen.get_monitor_geometry(monitor_num) monitor_right = monitor_area.x + monitor_area.width monitor_bottom = monitor_area.y + monitor_area.height if window_right > monitor_right: x = monitor_right - self.__toplevel.allocation.width else: x = cursor_right if window_bottom > monitor_bottom: # move the window just above the cursor so the window and a preedit string do not overlap. y = cursor_location[1] - self.__toplevel.allocation.height else: y = cursor_bottom self.move(x, y)
def show_url(url): """Open any @url with default viewer""" from gtk import show_uri, get_current_event_time from gtk.gdk import screen_get_default from glib import GError try: show_uri(screen_get_default(), url, get_current_event_time()) except GError, e: logger.error("Error in gtk.show_uri: " + e)
def show_url(url): """Open any @url with default viewer""" from gtk import show_uri, get_current_event_time from gtk.gdk import screen_get_default from glib import GError try: pretty.print_debug(__name__, "show_url", url) return show_uri(screen_get_default(), url, get_current_event_time()) except GError, exc: pretty.print_error(__name__, "gtk.show_uri:", exc)
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()
def main(args): global pixmap width = 544 height = 100 screen = gdk.screen_get_default( ) win = gtk.Window( ) win.set_title( 'Spectrumize' ) win.set_default_size( width, height ) win.stick( ) win.set_keep_below( True ) win.set_decorated( False ) win.set_skip_taskbar_hint( True ) #win.set_gravity( gdk.GRAVITY_CENTER ) win.connect( 'delete-event', gtk.main_quit ) win.connect( 'expose-event', expose ) win.connect( 'screen-changed', screenChanged ) # initialize for the current display screenChanged( win ) # Run the program win.show_all( ) pixmap = gdk.Pixmap( win.window, width, height, -1 ) # Tell GTK+ that we want to draw the windows background ourself. win.set_app_paintable( True ) win.set_double_buffered( False ) screen_rect = screen.get_monitor_geometry( 0 ) win.move( screen_rect.width / 2 - width / 2 + screen_rect.x, screen_rect.height / 2 - height / 2 + screen_rect.y ) gobject.timeout_add( 33, timerExecFrame, win ) try: gtk.main( ) except KeyboardInterrupt: pass print total_peak_heights return True
def get_core_encodings(self): encodings = GTKXpraClient.get_core_encodings(self) if gdk.screen_get_default().get_rgba_visual() is not None: try: #check for bytearray which is used by PixmapBacking #to unpremultiply rgb32 data bytearray("") from xpra.codecs.argb.argb import unpremultiply_argb_in_place assert unpremultiply_argb_in_place encodings.append("rgb32") except: pass #gtk2 can handle 'png' and 'jpeg' natively (without PIL) #(though using PIL is better since we can do that in the decode thread) for x in ("png", "jpeg"): if x not in encodings: encodings.append(x) return encodings
def __init__(self, name, startup_id=None): gobject.GObject.__init__(self) self._is_running = False self._name = name self._screen = gdk.screen_get_default() # TODO: Find out what the startup_id is meant to be. self._startup_id = startup_id self.sess_bus = dbus.SessionBus() lock = "%s.lock" % name #"org.gtk.PyUnique.lock" good_requests = [ dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER, dbus.bus.REQUEST_NAME_REPLY_ALREADY_OWNER ] # Acquire dbus "lock" - I don't want multiple processes # starting at once. while self.sess_bus.request_name(lock) not in good_requests: time.sleep(0.1) # So when we've arrived here, we're sure to be the only # process executing this. A FIXME would be that this lock is a # global lock for all PyUnique applications that hasn't # modified the lock string themselves. Perhaps we should # incorporate self.name into the locking string? try: # Try to get the object of the already running UniqueApp # instance. If this succeeds, there is another instance # running, therefore we can set the is-running property. self.running_process = self.sess_bus.get_object( self.props.name, "/Factory") self.set_property('is-running', True) except dbus.DBusException: # We got a DBus exception. This means that most likely, # noone is listening at the object path. The is-running is # left at its default False state. self.busname = dbus.service.BusName(self._name, self.sess_bus) self.busobj = UniqueDBusObject(self.sess_bus, "/Factory", self) self.sess_bus.release_name(lock)
def __init__ (self): super(LanguageBar, self).__init__() self.__show = 1 self.__enabled = False self.__has_focus = False self.__show_im_name = False self.__im_name = None self.set_style(gtk.TOOLBAR_BOTH_HORIZ) self.set_show_arrow(False) self.set_property("icon-size", ICON_SIZE) self.__create_ui() self.__properties = [] self.__toplevel = gtk.Window(gtk.WINDOW_POPUP) self.__toplevel.connect("size-allocate", self.__toplevel_size_allocate_cb) self.__toplevel.add(self) self.__screen = gdk.screen_get_default() self.__screen.connect("size-changed", self.__screen_size_changed_cb) self.set_position(-1, -1)
def __init__(self, name, startup_id=None): gobject.GObject.__init__(self) self._is_running = False self._name = name self._screen = gdk.screen_get_default() # TODO: Find out what the startup_id is meant to be. self._startup_id = startup_id self.sess_bus = dbus.SessionBus() lock = "%s.lock" % name #"org.gtk.PyUnique.lock" good_requests = [dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER, dbus.bus.REQUEST_NAME_REPLY_ALREADY_OWNER] # Acquire dbus "lock" - I don't want multiple processes # starting at once. while self.sess_bus.request_name(lock) not in good_requests: time.sleep(0.1) # So when we've arrived here, we're sure to be the only # process executing this. A FIXME would be that this lock is a # global lock for all PyUnique applications that hasn't # modified the lock string themselves. Perhaps we should # incorporate self.name into the locking string? try: # Try to get the object of the already running UniqueApp # instance. If this succeeds, there is another instance # running, therefore we can set the is-running property. self.running_process = self.sess_bus.get_object(self.props.name, "/Factory") self.set_property('is-running', True) except dbus.DBusException: # We got a DBus exception. This means that most likely, # noone is listening at the object path. The is-running is # left at its default False state. self.busname = dbus.service.BusName(self._name, self.sess_bus) self.busobj = UniqueDBusObject(self.sess_bus, "/Factory", self) self.sess_bus.release_name(lock)
def main(): """ Main function. In memory of good old languages *snicker* """ args = argument_parser() screen = gdk.screen_get_default() active_window = screen.get_active_window() active_window.unmaximize() workarea = get_workarea() borders = get_borders(active_window) place_dic = {"x": 0, "y": 0, "width": 0, "height": 0} position = args.position ### Define the x ### if position in [1, 2, 4, 5, 7, 8]: place_dic["x"] = int(workarea[0]) else: place_dic["x"] = int(workarea[0] + round(float(workarea[2]) / 2.0)) ### Define the y ### if position in [4, 5, 6, 7, 8, 9]: place_dic["y"] = int(workarea[1]) else: place_dic["y"] = int(workarea[1] + round(float(workarea[3]) / 2.0)) ### Define the width ### if position in [2, 5, 8]: place_dic["width"] = int(workarea[2] - (borders[0] + borders[1])) else: place_dic["width"] = int( round(float(workarea[2]) / 2.0) - (borders[0] + borders[1])) ### Define the height ### if position in [4, 5, 6]: place_dic["height"] = int(workarea[3] - (borders[2] + borders[3])) else: place_dic["height"] = int( round(float(workarea[3]) / 2.0) - (borders[2] + borders[3])) active_window.move_resize(place_dic["x"], place_dic["y"], place_dic["width"], place_dic["height"]) active_window.get_geometry() gdk.exit((0))
def __init__ (self): super(LanguageBar, self).__init__() self.__show = 0 self.__enabled = False self.__has_focus = False self.__show_im_name = False self.__im_name = None self.__props = None self.__selected_menu_item = None self.set_style(gtk.TOOLBAR_BOTH_HORIZ) self.set_show_arrow(False) self.set_property("icon-size", ICON_SIZE) self.__create_ui() self.__properties = [] self.__toplevel = gtk.Window(gtk.WINDOW_POPUP) self.__toplevel.connect("size-allocate", self.__toplevel_size_allocate_cb) self.__toplevel.add(self) self.__screen = gdk.screen_get_default() self.__screen.connect("size-changed", self.__screen_size_changed_cb) self.set_position(-1, -1)
def __init__(self, position): gtk.Window.__init__(self) self.hover = False self.size = style.GRID_CELL_SIZE + style.LINE_WIDTH accel_group = gtk.AccelGroup() self.set_data('sugar-accel-group', accel_group) self.add_accel_group(accel_group) self._position = position self.set_decorated(False) self.connect('realize', self._realize_cb) self.connect('enter-notify-event', self._enter_notify_cb) self.connect('leave-notify-event', self._leave_notify_cb) self._container = FrameContainer(position) self.add(self._container) self._container.show() self._update_size() screen = gdk.screen_get_default() screen.connect('size-changed', self._size_changed_cb)
def _createUi(self): """ Creates the Viewer GUI """ # drawing area self.aframe = gtk.AspectFrame(xalign=0.5, yalign=0.5, ratio=4.0 / 3.0, obey_child=False) self.pack_start(self.aframe, expand=True) self.drawingarea = ViewerWidget(self.action) self.aframe.add(self.drawingarea) # Slider self.posadjust = gtk.Adjustment() self.slider = gtk.HScale(self.posadjust) self.slider.set_draw_value(False) self.slider.connect("button-press-event", self._sliderButtonPressCb) self.slider.connect("button-release-event", self._sliderButtonReleaseCb) self.slider.connect("scroll-event", self._sliderScrollCb) self.pack_start(self.slider, expand=False) self.moving_slider = False self.slider.set_sensitive(False) # Buttons/Controls bbox = gtk.HBox() boxalign = gtk.Alignment(xalign=0.5, yalign=0.5) boxalign.add(bbox) self.pack_start(boxalign, expand=False) self.rewind_button = gtk.ToolButton(gtk.STOCK_MEDIA_REWIND) self.rewind_button.connect("clicked", self._rewindCb) self.rewind_button.set_sensitive(False) bbox.pack_start(self.rewind_button, expand=False) self.back_button = gtk.ToolButton(gtk.STOCK_MEDIA_PREVIOUS) self.back_button.connect("clicked", self._backCb) self.back_button.set_sensitive(False) bbox.pack_start(self.back_button, expand=False) self.playpause_button = PlayPauseButton() self.playpause_button.connect("play", self._playButtonCb) bbox.pack_start(self.playpause_button, expand=False) self.playpause_button.set_sensitive(False) self.next_button = gtk.ToolButton(gtk.STOCK_MEDIA_NEXT) self.next_button.connect("clicked", self._nextCb) self.next_button.set_sensitive(False) bbox.pack_start(self.next_button, expand=False) self.forward_button = gtk.ToolButton(gtk.STOCK_MEDIA_FORWARD) self.forward_button.connect("clicked", self._forwardCb) self.forward_button.set_sensitive(False) bbox.pack_start(self.forward_button, expand=False) # current time self.timelabel = gtk.Label() self.timelabel.set_markup("<tt>00:00:00.000</tt>") self.timelabel.set_alignment(1.0, 0.5) bbox.pack_start(self.timelabel, expand=False, padding=10) self._haveUI = True screen = gdk.screen_get_default() height = screen.get_height() if height >= 800: # show the controls and force the aspect frame to have at least the same # width (+110, which is a magic number to minimize dead padding). bbox.show_all() width, height = bbox.size_request() width += 110 height = int(width / self.aframe.props.ratio) self.aframe.set_size_request(width, height)
def _createUi(self): """ Creates the Viewer GUI """ # drawing area self.aframe = gtk.AspectFrame(xalign=0.5, yalign=0.5, ratio=4.0 / 3.0, obey_child=False) self.pack_start(self.aframe, expand=True) self.internal = ViewerWidget(self.action) self.internal.show() self.aframe.add(self.internal) self.external_window = gtk.Window() vbox = gtk.VBox() vbox.set_spacing(SPACING) self.external_window.add(vbox) self.external = ViewerWidget(self.action) vbox.pack_start(self.external) self.external_window.connect("delete-event", self._externalWindowDeleteCb) self.external_window.connect("configure-event", self._externalWindowConfigureCb) self.external_vbox = vbox self.external_vbox.show_all() # Slider self.posadjust = gtk.Adjustment() self.slider = gtk.HScale(self.posadjust) self.slider.set_draw_value(False) self.slider.connect("button-press-event", self._sliderButtonPressCb) self.slider.connect("button-release-event", self._sliderButtonReleaseCb) self.slider.connect("scroll-event", self._sliderScrollCb) self.pack_start(self.slider, expand=False) self.moving_slider = False self.slider.set_sensitive(False) # Buttons/Controls bbox = gtk.HBox() boxalign = gtk.Alignment(xalign=0.5, yalign=0.5) boxalign.add(bbox) self.pack_start(boxalign, expand=False) self.goToStart_button = gtk.ToolButton(gtk.STOCK_MEDIA_PREVIOUS) self.goToStart_button.connect("clicked", self._goToStartCb) self.goToStart_button.set_tooltip_text( _("Go to the beginning of the timeline")) self.goToStart_button.set_sensitive(False) bbox.pack_start(self.goToStart_button, expand=False) self.back_button = gtk.ToolButton(gtk.STOCK_MEDIA_REWIND) self.back_button.connect("clicked", self._backCb) self.back_button.set_tooltip_text(_("Go back one second")) self.back_button.set_sensitive(False) bbox.pack_start(self.back_button, expand=False) self.playpause_button = PlayPauseButton() self.playpause_button.connect("play", self._playButtonCb) bbox.pack_start(self.playpause_button, expand=False) self.playpause_button.set_sensitive(False) self.forward_button = gtk.ToolButton(gtk.STOCK_MEDIA_FORWARD) self.forward_button.connect("clicked", self._forwardCb) self.forward_button.set_tooltip_text(_("Go forward one second")) self.forward_button.set_sensitive(False) bbox.pack_start(self.forward_button, expand=False) self.goToEnd_button = gtk.ToolButton(gtk.STOCK_MEDIA_NEXT) self.goToEnd_button.connect("clicked", self._goToEndCb) self.goToEnd_button.set_tooltip_text( _("Go to the end of the timeline")) self.goToEnd_button.set_sensitive(False) bbox.pack_start(self.goToEnd_button, expand=False) # current time self.timecode_entry = TimeWidget() self.timecode_entry.setWidgetValue(0) self.timecode_entry.connect("value-changed", self._jumpToTimecodeCb) self.timecode_entry.connectFocusEvents(self._entryFocusInCb, self._entryFocusOutCb) bbox.pack_start(self.timecode_entry, expand=False, padding=10) self._haveUI = True screen = gdk.screen_get_default() height = screen.get_height() if height >= 800: # show the controls and force the aspect frame to have at least the same # width (+110, which is a magic number to minimize dead padding). bbox.show_all() width, height = bbox.size_request() width += 110 height = int(width / self.aframe.props.ratio) self.aframe.set_size_request(width, height) self.show_all() self.buttons = boxalign
def _createUi(self): """ Creates the Viewer GUI """ # drawing area self.aframe = gtk.AspectFrame(xalign=0.5, yalign=0.5, ratio=4.0 / 3.0, obey_child=False) self.internal = ViewerWidget(self.action, self.app.settings) self.internal.init_transformation_events() self.internal.show() self.aframe.add(self.internal) self.pack_start(self.aframe, expand=True) self.external_window = gtk.Window() vbox = gtk.VBox() vbox.set_spacing(SPACING) self.external_window.add(vbox) self.external = ViewerWidget(self.action, self.app.settings) vbox.pack_start(self.external) self.external_window.connect("delete-event", self._externalWindowDeleteCb) self.external_window.connect("configure-event", self._externalWindowConfigureCb) self.external_vbox = vbox self.external_vbox.show_all() # Slider self.posadjust = gtk.Adjustment() self.slider = gtk.HScale(self.posadjust) self.slider.set_draw_value(False) self.slider.connect("button-press-event", self._sliderButtonPressCb) self.slider.connect("button-release-event", self._sliderButtonReleaseCb) self.slider.connect("scroll-event", self._sliderScrollCb) self.pack_start(self.slider, expand=False) self.moving_slider = False self.slider.set_sensitive(False) # Buttons/Controls bbox = gtk.HBox() boxalign = gtk.Alignment(xalign=0.5, yalign=0.5) boxalign.add(bbox) self.pack_start(boxalign, expand=False) self.goToStart_button = gtk.ToolButton(gtk.STOCK_MEDIA_PREVIOUS) self.goToStart_button.connect("clicked", self._goToStartCb) self.goToStart_button.set_tooltip_text(_("Go to the beginning of the timeline")) self.goToStart_button.set_sensitive(False) bbox.pack_start(self.goToStart_button, expand=False) self.back_button = gtk.ToolButton(gtk.STOCK_MEDIA_REWIND) self.back_button.connect("clicked", self._backCb) self.back_button.set_tooltip_text(_("Go back one second")) self.back_button.set_sensitive(False) bbox.pack_start(self.back_button, expand=False) self.playpause_button = PlayPauseButton() self.playpause_button.connect("play", self._playButtonCb) bbox.pack_start(self.playpause_button, expand=False) self.playpause_button.set_sensitive(False) self.forward_button = gtk.ToolButton(gtk.STOCK_MEDIA_FORWARD) self.forward_button.connect("clicked", self._forwardCb) self.forward_button.set_tooltip_text(_("Go forward one second")) self.forward_button.set_sensitive(False) bbox.pack_start(self.forward_button, expand=False) self.goToEnd_button = gtk.ToolButton(gtk.STOCK_MEDIA_NEXT) self.goToEnd_button.connect("clicked", self._goToEndCb) self.goToEnd_button.set_tooltip_text(_("Go to the end of the timeline")) self.goToEnd_button.set_sensitive(False) bbox.pack_start(self.goToEnd_button, expand=False) # current time self.timecode_entry = TimeWidget() self.timecode_entry.setWidgetValue(0) self.timecode_entry.connect("value-changed", self._jumpToTimecodeCb) self.timecode_entry.connectFocusEvents(self._entryFocusInCb, self._entryFocusOutCb) bbox.pack_start(self.timecode_entry, expand=False, padding=10) self._haveUI = True screen = gdk.screen_get_default() height = screen.get_height() if height >= 800: # show the controls and force the aspect frame to have at least the same # width (+110, which is a magic number to minimize dead padding). bbox.show_all() width, height = bbox.size_request() width += 110 height = int(width / self.aframe.props.ratio) self.aframe.set_size_request(width, height) self.show_all() self.buttons = boxalign
def has_transparency(self): return gdk.screen_get_default().get_rgba_visual() is not None
def get_default_screen_metrics( ): scrn = gdk.screen_get_default( ) h = scrn.get_height( ) w = scrn.get_width( ) return (w,h)
def _createUi(self): """ Creates the Viewer GUI """ # drawing area self.aframe = gtk.AspectFrame(xalign=0.5, yalign=0.5, ratio=4.0/3.0, obey_child=False) self.pack_start(self.aframe, expand=True) self.drawingarea = ViewerWidget(self.action) self.aframe.add(self.drawingarea) # Slider self.posadjust = gtk.Adjustment() self.slider = gtk.HScale(self.posadjust) self.slider.set_draw_value(False) self.slider.connect("button-press-event", self._sliderButtonPressCb) self.slider.connect("button-release-event", self._sliderButtonReleaseCb) self.slider.connect("scroll-event", self._sliderScrollCb) self.pack_start(self.slider, expand=False) self.moving_slider = False self.slider.set_sensitive(False) # Buttons/Controls bbox = gtk.HBox() boxalign = gtk.Alignment(xalign=0.5, yalign=0.5) boxalign.add(bbox) self.pack_start(boxalign, expand=False) self.goToStart_button = gtk.ToolButton(gtk.STOCK_MEDIA_PREVIOUS) self.goToStart_button.connect("clicked", self._goToStartCb) self.goToStart_button.set_tooltip_text(_("Go to the beginning of the timeline")) self.goToStart_button.set_sensitive(False) bbox.pack_start(self.goToStart_button, expand=False) self.back_button = gtk.ToolButton(gtk.STOCK_MEDIA_REWIND) self.back_button.connect("clicked", self._backCb) self.back_button.set_tooltip_text(_("Go back one second")) self.back_button.set_sensitive(False) bbox.pack_start(self.back_button, expand=False) self.playpause_button = PlayPauseButton() self.playpause_button.connect("play", self._playButtonCb) bbox.pack_start(self.playpause_button, expand=False) self.playpause_button.set_sensitive(False) self.forward_button = gtk.ToolButton(gtk.STOCK_MEDIA_FORWARD) self.forward_button.connect("clicked", self._forwardCb) self.forward_button.set_tooltip_text(_("Go forward one second")) self.forward_button.set_sensitive(False) bbox.pack_start(self.forward_button, expand=False) self.goToEnd_button = gtk.ToolButton(gtk.STOCK_MEDIA_NEXT) self.goToEnd_button.connect("clicked", self._goToEndCb) self.goToEnd_button.set_tooltip_text(_("Go to the end of the timeline")) self.goToEnd_button.set_sensitive(False) bbox.pack_start(self.goToEnd_button, expand=False) # current time self.timelabel = gtk.Label() self.timelabel.set_markup("<tt>00:00:00.000</tt>") self.timelabel.set_alignment(1.0, 0.5) bbox.pack_start(self.timelabel, expand=False, padding=10) self._haveUI = True screen = gdk.screen_get_default() height = screen.get_height() if height >= 800: # show the controls and force the aspect frame to have at least the same # width (+110, which is a magic number to minimize dead padding). bbox.show_all() width, height = bbox.size_request() width += 110 height = int(width / self.aframe.props.ratio) self.aframe.set_size_request(width , height) self.show_all()
#!/usr/bin/env python from gtk.gdk import screen_get_default from puush import screenshot if __name__ == '__main__': # Get the root and active window root = screen_get_default() if root.supports_net_wm_hint('_NET_ACTIVE_WINDOW') and root.supports_net_wm_hint('_NET_WM_WINDOW_TYPE'): # You definitely do not want to take a screen-shot of the whole desktop, see entry 23.36 for that # Returns something like ('ATOM', 32, ['_NET_WM_WINDOW_TYPE_DESKTOP']) active = root.get_active_window() if active.property_get('_NET_WM_WINDOW_TYPE')[-1][0] == '_NET_WM_WINDOW_TYPE_DESKTOP': exit(-1) # Calculate the size of the WM decorations relative_x, relative_y, win_w, win_h, d = active.get_geometry() width = win_w + (relative_x - 10) height = win_h + (relative_y - 10) # Calculate the position of where the WM decorations start (not the window itself) screenpos_x, screenpos_y = active.get_root_origin() else: exit(-1)
class NXSession: sname = None stype = 'unix-gnome' cache = '8M' images_cache = '32M' xcookie = None link = 'adsl' kbtype = 'pc102/us' nodelay = '1' backingstore = 'never' geometry = '800x600+112+59' media = '0' agent_server = '' agent_user = '' agent_password = '' screeninfo = '800x600x16+render' def __init__ (self, name, session_type = None): self.sname = name if session_type: self.stype = session_type f = os.popen ('xauth list :0 | awk \'{ print $3 }\'') self.xcookie = f.read ().strip () f.close () # we're probably under a GNOME session, let's try to grab the # info from gconf if os.getenv ('GNOME_DESKTOP_SESSION_ID'): f = os.popen ('gconftool-2 -g /desktop/gnome/peripherals/keyboard/xkb/model') tmp = f.read ().strip () f.close () if tmp: self.kbtype = tmp f = os.popen ('gconftool-2 -g /desktop/gnome/peripherals/keyboard/xkb/layouts | tr -d \'[\' | tr -d \']\' | cut -d \',\' -f 1') tmp = f.read ().strip () f.close () if tmp: self.kbtype += '/' + tmp else: self.kbtype = None # else, try to grab the keyboard setting from X itself if not self.kbtype: f = os.popen ('xprop -root | grep "^_XKB_RULES_NAMES(STRING)"') tmp = f.read () f.close () try: tmp = tmp.split ('"') self.kbtype = '%s/%s' % (tmp[3], tmp[5]) except AttributeError, IndexError: # raise an exception warning about the keyboard not # being detected? pass # detect screen information screen = gdk.screen_get_default () self.screeninfo = '%dx%dx%d+render' % \ (screen.get_width (), screen.get_height (), gdk.visual_get_best_depth ())
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)