def disabled_test_getDisplayRectsDoesNotLeak(self):
		"""
		Calling L{getDisplayRects} 100,000 times does not leak memory (you'll have to
		open taskmgr to make sure.)

		Disabled because Ivan manually confirmed that it does not leak.
		"""
		print("Open taskmgr.exe to make sure I'm not leaking memory right now.")
		for i in xrange(100000):
			getDisplayRects()
Esempio n. 2
0
    def disabled_test_getDisplayRectsDoesNotLeak(self):
        """
		Calling L{getDisplayRects} 100,000 times does not leak memory (you'll have to
		open taskmgr to make sure.)

		Disabled because Ivan manually confirmed that it does not leak.
		"""
        print(
            "Open taskmgr.exe to make sure I'm not leaking memory right now.")
        for i in range(100000):
            getDisplayRects()
Esempio n. 3
0
def image(image_type, monitor):
    if image_type:
        screenshot = getRectAsImage(getDisplayRects()[monitor])

        return {
            'message': 'Screenshot successfully captured',
            'screenshot': screenshot,
            'text_mode': 'success'
        }
    elif not image_type:
        cam = cv2.VideoCapture(monitor)

        check, frame = cam.read()
        if not check:
            raise Exception('Cam unavailable')

        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        frame = Image.fromarray(frame)

        cam.release()

        return {
            'message': 'Cam screenshot successfully captured',
            'screenshot': frame,
            'text_mode': 'success'
        }
    else:
        raise Exception('Error message')
Esempio n. 4
0
    def __init__(self, display_number, mode):
        self._display_number = display_number
        self._display_rect = getDisplayRects()[self._display_number - 1]
        self._mode = mode

        self.buy_back_count = 0
        self._result_counter = {"p1": {}, "p2": {}, "p3": {}, "p4": {}}
Esempio n. 5
0
 def Start_buttonOnActivated(self):
     if (self.meeting_start_hour, self.meeting_end_hour) < (self.meeting_end_hour, self.meeting_end_hour):
         screens = (getDisplayRects())
         rect = getRectAsImage(screens[self.capture_screen])
         # 요기 부분은 피드백을 위해 사진을 보여주는 부분이에여 나중에 서버로 전송하면 돼요!!
         # rect.save()
         rect.show()
         print("returned from function capture")
Esempio n. 6
0
 def screenCapture(self):
     loop = QEventLoop()
     QTimer.singleShot(self.capture_cycle * 1000, loop.quit)
     screens = (getDisplayRects())
     rect = getRectAsImage(screens[self.capture_screen])
     # 요기 부분은 피드백을 위해 사진을 보여주는 부분이에여 나중에 서버로 전송하면 돼요!!
     # rect.save()
     rect.show()
     print("screen captured")
     loop.exec_()
Esempio n. 7
0
def get_current_monitor():
    x, y = pyautogui.position()
    monitors = (getDisplayRects())

    for monitor in monitors:
        left, top, right, bottom = monitor
        if left <= x <= right:
            if top <= y <= bottom:
                return Monitor(monitor)

    return Monitor(monitors[0])
	def test_getDisplayRectsReturnsList(self):
		"""
		L{getDisplayRects} returns a list of length >= 1 with a tuple containing 4 integers,
		representing the geometry of each display.
		"""
		regions = getDisplayRects()
		##print("Display rects are:", regions)
		self.assertIsInstance(regions, list)
		for region in regions:
			self.assertIsInstance(region, tuple)
			for num in region:
				self.assertIsInstance(num, int)
Esempio n. 9
0
    def test_getDisplayRectsReturnsList(self):
        """
		L{getDisplayRects} returns a list of length >= 1 with a tuple containing 4 integers,
		representing the geometry of each display.
		"""
        regions = getDisplayRects()
        ##print("Display rects are:", regions)
        self.assertIsInstance(regions, list)
        for region in regions:
            self.assertIsInstance(region, tuple)
            for num in region:
                self.assertIsInstance(num, int)
Esempio n. 10
0
 def takeScreenShot(self):
     screen_rectangles = getDisplayRects()
     numberOfScreens = len(screen_rectangles)
     screenIndex = min(int(self.state["display_index"].get()) - 1, numberOfScreens)
     image = getRectAsImage(screen_rectangles[screenIndex]).convert("RGBA")
     self.state["imageProcessing"] = image
     self.state["imageProcessing"] = image
     self.mainCanvasFrame.text.delete("1.0", "end")
     self.attributes("-fullscreen", True)
     self.tkimage = ImageTk.PhotoImage(image)
     self.printScreenFrame.tkraise()
     self.printScreenFrame.overlayScreenLabel_canvas.config(width=screen_rectangles[screenIndex][0],
                                                            height=screen_rectangles[screenIndex][1])
     self.printScreenFrame.overlayScreenLabel_canvas.create_image(0, 0, anchor="nw", image=self.tkimage)
Esempio n. 11
0
def sel():
    var.get()
    sel_file = None
    if os.name == "posix":
        sel_file = open(
            os.path.expanduser(
                "~/Library/Application Support/Colouren/config.json"), 'w')
    elif os.name == "nt":
        sel_file = open(os.path.expanduser("~\Colouren\config.json"), 'w')
    if os.name == "nt" and len(getDisplayRects()) >= 2:
        Config['display'] = var.get()
    else:
        Config['display'] = 1
    sel_file.write(json.dumps(Config))
    sel_file.close()
Esempio n. 12
0
def main(addr):
    bridge = Bridge(addr)
    senderQ = Queue()
    senderP = Process(target=senderprocess, args=[bridge, senderQ])
    senderP.start()
    processpool, queuepool = list(
        zip(*map(lambda x: makeprocess(*x), zip(lights, [senderQ] * regions))))
    display = getDisplayRects()[1]

    # start = time.time()
    # for _ in range(15):
    while True:
        start = time.time()
        imDisplay = getRectAsImage(display)
        list(map(lambda x: x.put(imDisplay), queuepool))
        sleeptime = 0.2 - (time.time() - start)
        if sleeptime > 0:
            time.sleep(sleeptime)
Esempio n. 13
0
def initialize():
    config_dict = utility.get_config_dict()

    ip = config_dict['ip']
    username = config_dict['username']

    max_bri = config_dict['max_bri']
    min_bri = config_dict['min_bri']

    active_lights = [int(i) for i in config_dict['active'].split(',')]
    all_lights = [int(i) for i in config_dict['all_lights'].split(',')]

    # Check selected bulbs vs all known bulbs
    bulb_list = []
    for counter, bulb in enumerate(all_lights):
        if active_lights[counter]:
            bulb_list.append(active_lights[counter])
        else:
            bulb_list.append(0)

    bulb_settings = json.loads(config_dict['bulb_settings'])

    update = config_dict['update']
    update_buffer = config_dict['update_buffer']

    default = config_dict['default']

    zones = ast.literal_eval(config_dict['zones'])
    zone_state = bool(config_dict['zone_state'])

    party_mode = bool(config_dict['party_mode'])
    display_index = config_dict['display_index']

    sat = config_dict['sat']

    bbox = None
    if params.BUILD == 'win':
        from desktopmagic.screengrab_win32 import getDisplayRects
        bbox = getDisplayRects()[int(display_index)]

    return ip, username, bulb_list, bulb_settings, default, [], \
           update, update_buffer, max_bri, min_bri, zones, zone_state, \
           display_index, party_mode, sat, bbox
    def getScreenDepthVis(self):

        #Get screenshot from the second monitotr and crop just the DepthVis
        for displayNumber, rect in enumerate(getDisplayRects(), 1):
            if displayNumber == 2:
                screen = getRectAsImage(rect)

        screen = np.array(screen)

        DepthVis = screen[762:1000,
                          98:525]  # NOTE: its img[y: y + h, x: x + w]

        DepthVis_gray = cv2.cvtColor(DepthVis, cv2.COLOR_BGR2GRAY)

        small = cv2.resize(DepthVis_gray, (0, 0), fx=0.5, fy=0.5)

        #cv2.imshow("Test", DepthVis_gray)
        #cv2.waitKey(0)

        return DepthVis_gray
Esempio n. 15
0
 def take_screenshot(self, interval, screen_index):
     if self.screenshot_count == 0:
         self.screenshot_count = 1
     if self.running:
         file_path = self.entry_folder_select.get()
         file_name = self.entry_project_name.get() + '_' + str(
             self.screenshot_count) + '.png'
         if self.selected_screen.get(
         ) == 'Screen 1' or self.selected_screen.get() == 'Screen 2':
             screen = getRectAsImage(getDisplayRects()[screen_index])
             screen.save(os.path.join(file_path, file_name), format='png')
             self.screenshot_count += 1
             # ! change interval multiplication back to *60000
             self.callbacks.append(
                 self.root.after(
                     interval * self.MILLI_TO_MINS,
                     lambda: self.take_screenshot(
                         int(self.entry_interval.get()), screen_index)))
         elif self.selected_screen.get() == 'All screens':
             entire_screen = getScreenAsImage()
             entire_screen.save(os.path.join(file_path, file_name),
                                format='png')
             self.screenshot_count += 1
             self.callbacks.append(
                 self.root.after(
                     interval * self.MILLI_TO_MINS,
                     lambda: self.take_screenshot(
                         int(self.entry_interval.get()), screen_index)))
         elif self.selected_screen.get() == 'All screens (separate)':
             for screen_number, image in enumerate(getDisplaysAsImages(),
                                                   1):
                 file_name = self.entry_project_name.get() + '_' + str(self.screenshot_count)\
                             + '_screen' + str(screen_number) + '.png'
                 image.save(os.path.join(file_path, file_name),
                            format='png')
             self.screenshot_count += 1
             self.callbacks.append(
                 self.root.after(
                     interval * self.MILLI_TO_MINS,
                     lambda: self.take_screenshot(
                         int(self.entry_interval.get()), screen_index)))
Esempio n. 16
0
def calculate_and_send_packet():
    if not Pause:
        client = udp_client.SimpleUDPClient(Config['ip'], int(Config['port']))
        red = 0
        green = 0
        blue = 0
        desktop_image = None
        if os.name == "nt":
            desktop_image = getRectAsImage(
                getDisplayRects()[Config['display'] - 1])
        elif os.name == "posix":
            desktop_image = ImageGrab.grab()
        if Config['mode'] == 'average':
            for y in range(0, desktop_image.size[1], Optimisation):
                for x in range(0, desktop_image.size[0], Optimisation):
                    colour = desktop_image.getpixel((x, y))
                    red = red + colour[0]
                    green = green + colour[1]
                    blue = blue + colour[2]
            red = int(
                round((red / ((desktop_image.size[1] / Optimisation) *
                              (desktop_image.size[0] / Optimisation))), 0))
            green = int(
                round((green / ((desktop_image.size[1] / Optimisation) *
                                (desktop_image.size[0] / Optimisation))), 0))
            blue = int(
                round((blue / ((desktop_image.size[1] / Optimisation) *
                               (desktop_image.size[0] / Optimisation))), 0))
        elif Config['mode'] == 'dominant':
            color_thief = ColorThief(desktop_image)
            colours = color_thief.get_color(quality=25)
            red, green, blue = colours
        try:
            client.send_message("/red", red)
            client.send_message("/green", green)
            client.send_message("/blue", blue)
        except socket.error:
            print("Packet Missed")
    else:
        return
def main():
	print """\
This program constantly polls your display rect information and prints it when it changes.

This can be used to make sure getDisplayRects is free from desync bugs that occur
during monitor configuration changes.
"""
	lastRects = None
	count = 0
	start = time.time()
	while True:
		if count != 0 and count % 1000 == 0:
			end = time.time()
			##print end - start, "for 1000 calls"
			start = time.time()

		rects = getDisplayRects()
		if rects != lastRects:
			print rects
			lastRects = rects

		count += 1
Esempio n. 18
0
def stream_action(ip, port, resolution, monitor, fps):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((ip, port))

    headersize = state['settings']['headersize']
    encryption = state['settings']['encryption']
    encoding = state['settings']['encoding']
    mode = [True, 0, b'']

    while True:
        last_time = time.time()
        client_msg = s.recv(81920)

        if mode[0]:
            mode[1] = int(client_msg[:headersize])
            mode[0] = False

        mode[2] += client_msg

        if len(mode[2]) - headersize == mode[1]:
            frame = getRectAsImage(getDisplayRects()[monitor])
            frame = numpy.array(frame)
            frame = cv2.resize(frame, resolution)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

            if fps:
                cv2.putText(frame, f'{1.0 / (time.time() - last_time):.2f}',
                            (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0),
                            2)

            frame = pickle.dumps(frame)
            frame = zlib.compress(frame, 9)
            frame = encryption.do_encrypt(frame)

            final_msg = bytes(f'{len(frame):<{headersize}}', encoding) + frame
            s.send(final_msg)

            mode = [True, 0, b'']
def main():
    print("""\
This program constantly polls your display rect information and prints
it when it changes.

This can be used to make sure getDisplayRects is free from desync bugs
that occur during monitor configuration changes.
""")
    lastRects = None
    count = 0
    start = time.time()
    while True:
        if count != 0 and count % 1000 == 0:
            end = time.time()
            ##print(end - start, "for 1000 calls")
            start = time.time()

        rects = getDisplayRects()
        if rects != lastRects:
            print(rects)
            lastRects = rects

        count += 1
Esempio n. 20
0
def getDisplayRects(displays):
    monitors = SGw32.getDisplayRects()  # enumerate all displays
    #print(monitors)
    #return itemgetter(*displays)(monitors)
    return [monitors[i] for i in displays]
Esempio n. 21
0
def device_support(silent, io_channels):
  device_obj = {}

  try:
    device_obj['monitors'] = len(getDisplayRects())
  except:
    device_obj['monitors'] = '???'

  if silent:
    device_obj['cams'] = '???'
  else:
    cams = [0, []]

    while True:
      cam = cv2.VideoCapture(cams[0])
      check, frame = cam.read()
      if not check:
        break
      cams[0] += 1
      cams[1].append(f'[{int(cam.get(3))},{int(cam.get(4))}]')
    
    cam.release()
    device_obj['cams'] = '{} {}'.format(cams[0], ', '.join(cams[1]))

  try:
    p = pyaudio.PyAudio()
    CHUNK = 81920
    FORMAT = pyaudio.paInt16
    RATE = 44100
  except:
    device_obj['io-channels'] = '???'
  else:
    try:
      try:
        stream = p.open(format=FORMAT, channels=2, rate=RATE, input=True, output=False, frames_per_buffer=CHUNK)
        stream.stop_stream()
        stream.close()
        input_channels = '2'
      except:
        stream = p.open(format=FORMAT, channels=1, rate=RATE, input=True, output=False, frames_per_buffer=CHUNK)
        stream.stop_stream()
        stream.close()
        input_channels = '1'

      if io_channels[0] in ('1', '2'):
        device_obj['io-channels'] = '{}(+), '.format(input_channels)
      else:
        device_obj['io-channels'] = '{}(-), '.format(input_channels)
    except:
      device_obj['io-channels'] = 'None, '
    
    try:
      try:  
        stream = p.open(format=FORMAT, channels=2, rate=RATE, input=False, output=True, frames_per_buffer=CHUNK)
        stream.stop_stream()
        stream.close()
        output_channels = '2'
      except:
        stream = p.open(format=FORMAT, channels=1, rate=RATE, input=False, output=True, frames_per_buffer=CHUNK)
        stream.stop_stream()
        stream.close()
        output_channels = '1'
      
      if io_channels[1] in ('1', '2'):
        device_obj['io-channels'] += '{}(+)'.format(output_channels)
      else:
        device_obj['io-channels'] += '{}(-)'.format(output_channels)
    except:
      device_obj['io-channels'] += 'None'

    p.terminate()

  return device_obj
Esempio n. 22
0
def verify_monitor(display):
    '''Verify the monitor chosen is valid.'''
    if len(getDisplayRects()) <= display:
        return True
    return False
Esempio n. 23
0
 def get_image(self):
     '''Return an image from a specified display'''
     display = getDisplayRects()[
         self.monitor]  # get the dimensions of the monitor
     return getRectAsImage(display)
Esempio n. 24
0
def get_primary_monitor() -> Tuple[int, int, int, int]:
    """ Return the system's default primary monitor rectangle bounds. """
    return [rect for rect in getDisplayRects()
            if rect[:2] == (0, 0)][0]  # primary monitor has top left as 0, 0
Esempio n. 25
0
#!/usr/bin/env/python

from desktopmagic.screengrab_win32 import (getDisplayRects, getRectAsImage)

import sys, os
from PIL import Image

from PyQt4 import QtGui


numLeds = 32

screens = getDisplayRects()

class ScreenColors(QtGui.QWidget):
	def __init__(self):
		super(ScreenColors, self).__init__()
		
		self.forms = []
		
		self.InitUI()
	
	def InitUI(self):
		#create forms
		self.squareSize = 25
		self.setGeometry(50, 50, 512, 356)
		
		for x in range(numLeds):
			self.forms.append(QtGui.QFrame(self))
			self.forms[x].setStyleSheet("QWidget { background-color: %s }" % QtGui.QColor(0,0,0).name())
			if x < numLeds / 2:
Esempio n. 26
0
 def get_screens(self):
     for index, screen in enumerate(getDisplayRects()):
         self.screen_dict[index] = f'Screen {str(index + 1)}'
     return self.screen_dict
Esempio n. 27
0
from desktopmagic.screengrab_win32 import (getDisplayRects, saveScreenToBmp,
                                           saveRectToBmp, getScreenAsImage,
                                           getRectAsImage, getDisplaysAsImages)

# Save the entire virtual screen as a BMP (no PIL required)
saveScreenToBmp('screencapture_entire.bmp')

# Save an arbitrary rectangle of the virtual screen as a BMP (no PIL required)
saveRectToBmp('screencapture_256_256.bmp', rect=(0, 0, 256, 256))

# Save the entire virtual screen as a PNG
entireScreen = getScreenAsImage()
entireScreen.save('screencapture_entire.png', format='png')

# Get bounding rectangles for all displays, in display order
print("Display rects are:", getDisplayRects())
# -> something like [(0, 0, 1280, 1024), (-1280, 0, 0, 1024), (1280, -176, 3200, 1024)]

# Capture an arbitrary rectangle of the virtual screen: (left, top, right, bottom)
rect256 = getRectAsImage((0, 0, 256, 256))
rect256.save('screencapture_256_256.png', format='png')

# Unsynchronized capture, one display at a time.
# If you need all displays, use getDisplaysAsImages() instead.
for displayNumber, rect in enumerate(getDisplayRects(), 1):
    imDisplay = getRectAsImage(rect)
    imDisplay.save('screencapture_unsync_display_%d.png' % (displayNumber, ),
                   format='png')

# Synchronized capture, entire virtual screen at once, cropped to one Image per display.
for displayNumber, im in enumerate(getDisplaysAsImages(), 1):
Esempio n. 28
0
    def body(self, master):
        self.root_window = master.master.master
        self.logger = logging.getLogger(self.root_window.logger.name +
                                        '.SettingsDisplay')
        self.k = Keystroke_Watcher(self, sticky=True)
        # Labels
        Label(master, text="Avg. Monitor Default: ").grid(row=0, column=0)
        Label(master, text="Add Preset Color: ").grid(row=1, column=0)
        Label(master, text="Add keyboard shortcut").grid(row=2, column=0)

        # Widgets
        # Avg monitor color match
        self.avg_monitor = StringVar(
            master, value=config["AverageColor"]["DefaultMonitor"])
        options = []
        lst = getDisplayRects()
        for i in range(1, len(lst) + 1):
            els = [list(x) for x in itertools.combinations(lst, i)]
            options.extend(els)
        self.avg_monitor_dropdown = OptionMenu(master, self.avg_monitor, *lst,
                                               'all')

        # Custom preset color
        self.preset_color_name = Entry(master)
        self.preset_color_name.insert(END, "Enter color name...")
        self.preset_color_button = Button(master,
                                          text="Choose and add!",
                                          command=self.get_color)

        # Add keybindings
        lightnames = list(self.root_window.lightsdict.keys())
        self.keybind_bulb_selection = StringVar(master, value=lightnames[0])
        self.keybind_bulb_dropdown = OptionMenu(master,
                                                self.keybind_bulb_selection,
                                                *lightnames)
        self.keybind_keys_select = Entry(master)
        self.keybind_keys_select.insert(END, "Add key-combo...")
        self.keybind_keys_select.config(state='readonly')
        self.keybind_keys_select.bind('<FocusIn>', self.on_keybind_keys_click)
        self.keybind_keys_select.bind(
            '<FocusOut>',
            lambda *_: self.keybind_keys_select.config(state='readonly'))
        self.keybind_color_selection = StringVar(master, value="Color")
        self.keybind_color_dropdown = OptionMenu(
            master, self.keybind_color_selection, *self.root_window.framesdict[
                self.keybind_bulb_selection.get()].default_colors)
        self.keybind_add_button = Button(
            master,
            text="Add keybind",
            command=lambda *_: self.register_keybinding(
                self.keybind_bulb_selection.get(),
                self.keybind_keys_select.get(),
                self.keybind_color_selection.get()))
        self.keybind_delete_button = Button(master,
                                            text="Delete keybind",
                                            command=self.delete_keybind)

        # Insert
        self.avg_monitor_dropdown.grid(row=0, column=1)
        ttk.Separator(master, orient=HORIZONTAL).grid(row=0,
                                                      sticky='esw',
                                                      columnspan=100)
        self.preset_color_name.grid(row=1, column=1)
        self.preset_color_button.grid(row=1, column=2)
        ttk.Separator(master, orient=HORIZONTAL).grid(row=1,
                                                      sticky='esw',
                                                      columnspan=100)
        self.keybind_bulb_dropdown.grid(row=2, column=1)
        self.keybind_keys_select.grid(row=2, column=2)
        self.keybind_color_dropdown.grid(row=2, column=3)
        self.keybind_add_button.grid(row=2, column=4)
        self.mlb = MultiListbox(master,
                                (('Bulb', 5), ('Keybind', 5), ('Color', 5)))
        for keypress, fnx in dict(config['Keybinds']).items():
            label, color = fnx.split(':')
            self.mlb.insert(END, (label, keypress, color))
        self.mlb.grid(row=3, columnspan=100, sticky='esw')
        self.keybind_delete_button.grid(row=4, column=0)
 def fill_all_screens_geometry(self):
     #getDisplayRects()-> something like [(0, 0, 1280, 1024), (-1280, 0, 0, 1024), (1280, -176, 3200, 1024)]
     x_axis, y_axis = self.get_coordinates_for_position(getDisplayRects())
     left, top, right, bottom = min(x_axis), min(y_axis), abs(min(x_axis)) + max(x_axis), abs(min(y_axis)) + max(y_axis)
     self.setGeometry(left, top, right, bottom)
     return
Esempio n. 30
0
def get_current_bbox():
    return getDisplayRects()[0]
Esempio n. 31
0
                                  image=desktop_3_image,
                                  variable=var,
                                  value=3,
                                  command=sel)
    desktop_3_panel.pack(side="top", expand=True)

    # Radio Button and Labels
    desktop_1_label = Radiobutton(left_frame,
                                  text="Display 1",
                                  variable=var,
                                  value=1,
                                  command=sel,
                                  bg='grey')
    desktop_1_label.pack(side="top")

    if os.name == "nt" and len(getDisplayRects()) >= 2:
        desktop_2_label = Radiobutton(middle_frame,
                                      text="Display 2",
                                      variable=var,
                                      value=2,
                                      command=sel,
                                      bg='grey')
    else:
        desktop_2_label = Radiobutton(middle_frame,
                                      text="Not Available",
                                      variable=var,
                                      value=2,
                                      command=sel,
                                      bg='grey')
    desktop_2_label.pack(side="top")
Esempio n. 32
0
    def body(self, master):
        self.root_window = master.master.master  # This is really gross. I'm sorry.
        self.logger = logging.getLogger(self.root_window.logger.name + '.SettingsDisplay')
        self.key_listener = KeybindManager(self, sticky=True)
        # Labels
        Label(master, text="Start Minimized?: ").grid(row=0, column=0)
        Label(master, text="Avg. Monitor Default: ").grid(row=1, column=0)
        Label(master, text="Smooth Transition Time (sec): ").grid(row=2, column=0)
        Label(master, text="Brightness Offset: ").grid(row=3, column=0)
        Label(master, text="Add Preset Color: ").grid(row=4, column=0)
        Label(master, text="Audio Input Source: ").grid(row=5, column=0)
        Label(master, text="Add keyboard shortcut").grid(row=6, column=0)

        # Widgets
        # Starting minimized
        self.start_mini = BooleanVar(master, value=config.getboolean("AppSettings", "start_minimized"))
        self.start_mini_check = Checkbutton(master, variable=self.start_mini)

        # Avg monitor color match
        self.avg_monitor = StringVar(master, value=config["AverageColor"]["DefaultMonitor"])
        options = ['full', 'get_primary_monitor', *getDisplayRects()]
        # lst = getDisplayRects()
        # for i in range(1, len(lst) + 1):
        #    els = [list(x) for x in itertools.combinations(lst, i)]
        #    options.extend(els)
        self.avg_monitor_dropdown = OptionMenu(master, self.avg_monitor, *options)

        self.duration_scale = Scale(master, from_=0, to_=2, resolution=1 / 15, orient=HORIZONTAL)
        self.duration_scale.set(float(config["AverageColor"]["Duration"]))

        self.brightness_offset = Scale(master, from_=0, to_=65535, resolution=1, orient=HORIZONTAL)
        self.brightness_offset.set(int(config["AverageColor"]["brightnessoffset"]))

        # Custom preset color
        self.preset_color_name = Entry(master)
        self.preset_color_name.insert(END, "Enter color name...")
        self.preset_color_button = Button(master, text="Choose and add!", command=self.get_color)

        # Audio dropdown
        device_names = self.master.audio_interface.get_device_names()
        try:
            init_string = " " + config["Audio"]["InputIndex"] + " " + device_names[int(config["Audio"]["InputIndex"])]
        except ValueError:
            init_string = " None"
        self.audio_source = StringVar(master,
                                      init_string)  # AudioSource index is grabbed from [1], so add a space at [0]
        as_choices = device_names.items()
        self.as_dropdown = OptionMenu(master, self.audio_source, *as_choices)

        # Add keybindings
        lightnames = list(self.root_window.lightsdict.keys())
        self.keybind_bulb_selection = StringVar(master, value=lightnames[0])
        self.keybind_bulb_dropdown = OptionMenu(master, self.keybind_bulb_selection,
                                                *lightnames)
        self.keybind_keys_select = Entry(master)
        self.keybind_keys_select.insert(END, "Add key-combo...")
        self.keybind_keys_select.config(state='readonly')
        self.keybind_keys_select.bind('<FocusIn>', self.on_keybind_keys_click)
        self.keybind_keys_select.bind('<FocusOut>', lambda *_: self.keybind_keys_select.config(state='readonly'))
        self.keybind_color_selection = StringVar(master, value="Color")
        self.keybind_color_dropdown = OptionMenu(master, self.keybind_color_selection,
                                                 *self.root_window.framesdict[
                                                     self.keybind_bulb_selection.get()].default_colors,
                                                 *(
                                                     [*config["PresetColors"].keys()] if any(
                                                         config["PresetColors"].keys()) else [None])
                                                 )
        self.keybind_add_button = Button(master, text="Add keybind",
                                         command=lambda *_: self.register_keybinding(
                                             self.keybind_bulb_selection.get(), self.keybind_keys_select.get(),
                                             self.keybind_color_selection.get()))
        self.keybind_delete_button = Button(master, text="Delete keybind", command=self.delete_keybind)

        # Insert
        self.start_mini_check.grid(row=0, column=1)
        ttk.Separator(master, orient=HORIZONTAL).grid(row=0, sticky='esw', columnspan=100)
        self.avg_monitor_dropdown.grid(row=1, column=1)
        self.duration_scale.grid(row=2, column=1)
        self.brightness_offset.grid(row=3, column=1)
        ttk.Separator(master, orient=HORIZONTAL).grid(row=3, sticky='esw', columnspan=100)
        self.preset_color_name.grid(row=4, column=1)
        self.preset_color_button.grid(row=4, column=2)
        ttk.Separator(master, orient=HORIZONTAL).grid(row=4, sticky='esw', columnspan=100)
        self.as_dropdown.grid(row=5, column=1)
        ttk.Separator(master, orient=HORIZONTAL).grid(row=5, sticky='esw', columnspan=100)
        self.keybind_bulb_dropdown.grid(row=6, column=1)
        self.keybind_keys_select.grid(row=6, column=2)
        self.keybind_color_dropdown.grid(row=6, column=3)
        self.keybind_add_button.grid(row=6, column=4)
        self.mlb = MultiListbox(master, (('Bulb', 5), ('Keybind', 5), ('Color', 5)))
        for keypress, fnx in dict(config['Keybinds']).items():
            label, color = fnx.split(':')
            self.mlb.insert(END, (label, keypress, color))
        self.mlb.grid(row=7, columnspan=100, sticky='esw')
        self.keybind_delete_button.grid(row=8, column=0)