#!/usr/bin/env python import os import sys import subprocess import termios import tty import readline import math readline.parse_and_bind('tab: complete') readline.parse_and_bind('set editing-mode vi') def termsize(): rows, columns = os.popen('stty size', 'r').read().split() return (int(rows),int(columns)) class bc: MAG = '\033[95m' BLU = '\033[94m' GRE = '\033[92m' YEL = '\033[93m' RED = '\033[91m' CYA = '\033[96m' WHI = '\033[1m' END = '\033[0m' CLR = '\033[2J' def disable(self): self.MAG = '' self.BLU = '' self.GRE = '' self.YEL = '' self.RED = '' self.END = '' self.CLR = '' self.CYA = '' self.WHI = '' def pos(self,y,x): return "\033["+str(y)+";"+str(x)+"H" class getch: def __init__(self): import sys, tty, termios def get(self): fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch def ichr(i): ''' convert integer to 1-9, a-z, A-Z, omitting x ''' if i < 10: return str(i) i=i + 87 if i>119: i=i+1 if i>122: i=i-122+64 return chr(i) def drawmenu(entries): maxrows,maxcolumns = termsize() maxrows-=5 maxcolumns-=10 twocol=False co=bc() helptext="" print(co.END+co.CLR+co.pos(1,3)+co.YEL+'XRandrMenu x:exit '+helptext+co.END) if len(entries)>20: twocol=True maxrows=int(math.ceil(min(maxrows/2.0, len(entries)/2.0))) maxcolumns=int(math.ceil(maxcolumns/2.0)) r=1 for e in range(len(entries)): if r>maxrows: break printline=entries[e][2] if len(printline)>maxcolumns: printline=printline[:maxcolumns]+"..." print(co.WHI+entries[e][0]+co.END+' '+entries[e][3]+printline+co.END) r=1+r if twocol: r=1 for e in range(e,len(entries)): if r>maxrows: break printline=entries[e][2] if len(printline)>maxcolumns: printline=printline[:maxcolumns]+"..." print(co.pos(r+1,maxcolumns)+'| '+co.WHI+entries[e][0]+co.END+' '+entries[e][3]+printline+co.END) r=1+r print(co.pos(maxrows+2,0)) def read_displays(): proc = subprocess.Popen('xrandr', stdout=subprocess.PIPE) output = proc.stdout.read() entries=[] connected=False for line in output.split('\n'): try: idx=int(line[1:2]) entries.append([line[1:3], line[4:]]) except: pass return entries def append_index(entries,offset=0,color=None): e=1+offset for el in range(len(entries)): entries[el]=[ichr(e), entries[el][0], entries[el][1], color] e=e+1 return entries def launch(key,entries,args=""): ''' launch the given resolution ''' idx=[i for i in range(len(entries)) if entries[i][0]==key][0] command_str=['xrandr','--size',entries[idx][1]] try: subprocess.call(command_str) except: print('Unable to run:') print(command_str) def initialize(): entries=read_displays() entries=append_index(entries,offset=0,color=bc.CYA) return entries def main(): arg_input=None if (len(sys.argv)>1): if (sys.argv[1]=="-h"): print("Start within a VNC session to select different screen resolutions") sys.exit(0) arg_input=sys.argv[1] entries=initialize() print(entries) ch=getch() drawmenu(entries) while True: if arg_input: inkey=ord(arg_input) else: inkey=ord(ch.get()) #print('-'+str((inkey))+'-') if inkey in [120,27,3,24,4]: sys.exit(0) if inkey==46: # . entries=initialize() if chr(inkey) in [x[0] for x in entries]: launch(chr(inkey),entries) entries=initialize() if arg_input: sys.exit(0) drawmenu(entries) main()