#!/usr/bin/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][1]+" "+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][1]+" "+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'): if line.find(" connected ")!=-1: connected=True cols=line.split(" ") display=cols[0] if cols[2][0]!="(": mode=cols[2] else: mode="" entries.append([display,'off']) continue if line.find(" disconnected ")!=-1: connected=False continue if connected: cols=line.split(" ") entries.append([display,cols[3]]) entries.sort(key=lambda x: x[0]) 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] if entries[idx][2]=="off": command_str=['xrandr','--output',entries[idx][1],'--off'] else: command_str=['xrandr','--output',entries[idx][1],'--mode',entries[idx][2]] 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(): entries=initialize() print(entries) ch=getch() drawmenu(entries) while True: 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() drawmenu(entries) main()