def simple_start_menu(): #https://github.com/m-col/qtile-config/blob/master/notification.py #TODO move definitions outside of this function so that they are only called once #i.e. popup = should be outside but popup.place should remain try: #log_test(1) popup = Popup(qtile, background="#002200", x=0, y=24, width=100, height=50, font_size=10, border="#ff00ff", border_width=1, foreground="#ffffff", opacity=0.9) popup.place() popup.unhide() popup.text = "Reboot Shutdown" popup.draw_text(x=2, y=popup.height-popup.font_size-1) # TODO don't hard code this #log_test(2) popup.draw() #log_test(3) #popup.win.window.set_property("_NET_WM_STATE", "Above") popup.win.window.set_property("_NET_WM_NAME", "simple start menu") popup.win.update_name() try: # TODO simplify this mess icon_file_list = ["/home/yobleck/.config/qtile/icons/system-reboot.svg", "/home/yobleck/.config/qtile/icons/system-shutdown.svg"] icon_list = [images.Img.from_path(f) for f in icon_file_list] [i.resize(height=popup.height) for i in icon_list] surface_list = [] for x in icon_list: s, _ = images._decode_to_image_surface(x.bytes_img, x.width, x.height) surface_list.append(s) [popup.draw_image(s, int(popup.width/len(surface_list))*i, -5) for i, s in enumerate(surface_list)] #log_test(4) except Exception as e: log_test(f"image_load error: {e}") def click(x, y, button): action_list = ["systemctl reboot", "systemctl poweroff"] try: if button == 1: x_pos = int(x/popup.width*len(action_list)) #log_test("clicked on: " + action_list[x_pos]) qtile.cmd_spawn(action_list[x_pos]) else: popup.hide() popup.kill() except Exception as e: log_test(f"click error: {e}") popup.win.process_button_click = click def leave(*args): try: #log_test(args) popup.hide() popup.kill() except Exception as e: log_test(f"leave error: {e}") popup.win.process_pointer_leave = leave except Exception as e: log_test(f"popup_test error: {e}")
def simple_repl(): # old config hack version. see updated widget version try: popup = Popup(qtile, background="#000000", foreground="#00aa00", x=1280, y=720, width=500, height=500, font="Noto Mono", font_size=12, border=["#0000ff", "#0000ff", "#ffff00", "#ffff00"], border_width=5, opacity=0.90, wrap=True) popup.layout.markup = False # TODO PR to add this to popup options popup.layout.width = popup.width # actually enforce line wrap. see PR above popup.place() popup.unhide() #num_cols = popup.width//8 # 8 assumes Noto Mono font at size 12 #num_rows = popup.height//15 # ditto nl = "\n" old_text = ["Yobleck's simple python REPL (click to focus, esc to quit, F5/'cls'/'clear' to reset screen)", f"Qtile: {metadata.distribution('qtile').version}", f"Python: {sys.version.replace(nl, '')}", ">>> "] new_text = "" popup.text = lines_to_text(old_text) + "\u2588" #[-num_rows:] draw_y = 5 popup.draw_text(x=2, y=draw_y) popup.draw() #globals()["tert"] = "terting" history = [] # command history for this popup instance. save across session with global var? history_index = -1 # is there a way to do this without the var? indentation_level = 0 def key_press(keycode): try: nonlocal new_text nonlocal old_text nonlocal draw_y nonlocal history_index nonlocal indentation_level keychr = chr(keycode) log_test(f"key {keycode}={keychr} pressed") # TODO convert keycodes to text if keycode == 65307: # escape leave() return elif keycode == 65474: # F5 to clear screen old_text = [">>> "] new_text = "" # scrolling elif keycode == 65366: # page down draw_y -= 5 elif keycode == 65365: # page up draw_y += 5 elif keycode == 65288: # backspace if new_text[-1] == "\n": indentation_level -= 1 new_text = new_text[:-1] elif keycode == 65289: # tab. NOTE probably never going to have tab completion new_text += "\t" # history elif keycode in [65362, 65364]: # up/down arrow keys. TODO double check with another non 60% keyboard if history: if keycode == 65362 and history_index < len(history)-1: history_index += 1 new_text = history[history_index] elif keycode == 65364 and history_index > 0: history_index -= 1 new_text = history[history_index] elif keycode == 65293: # enter history.insert(0, new_text) history_index = -1 if new_text: if new_text in ["exit", "exit()", "quit", "quit()"] or "sys.exit" in new_text: # exit commands. WARNING will eval("quit()") kill qtile? sys.exit solution will kill regardless of conditionals leave() return elif new_text in ["clear", "cls"]: # clear screen commands old_text = [">>> "] new_text = "" elif new_text[-1] == ":": indentation_level += 1 new_text += "\n" + " "*indentation_level else: #old_text += new_text + "\n" + _simple_eval_exec(new_text) + ">>> " # append input text, eval and append results old_text[-1] += new_text old_text.extend([ _simple_eval_exec(new_text), ">>> "]) new_text = "" indentation_level = 0 elif keycode in [65505, 65507, 65508, 65506, 65513, 65514, 65515]: # range(65505, 65518) for mod keys? pass # ignore modifiers and other non text keys. TODO modifier list that is cleared after non modifier is pressed. act on list? else: new_text += keychr # actually drawing text popup.clear() popup.text = lines_to_text(old_text) + new_text + "\u2588" # TODO scroll to bottom after hitting enter popup.draw_text(x=2, y=draw_y) popup.draw() popup.text = lines_to_text(old_text) #[-num_rows:] [-num_rows:] except Exception as e: log_test(f"key press error: {e}") popup.win.process_key_press = key_press def leave(*args): # close window when mouse leaves try: log_test("pointer leave") popup.hide() popup.kill() except Exception as e: log_test(f"pointer leave error: {e}") #popup.win.process_pointer_leave = leave # focus window def b_press(x, y, button): # two functions cause mouse click doesn't work with *args try: nonlocal draw_y if button == 1: popup.win.focus(warp=False) elif button in [4,5]: if button == 4: # mouse wheel up draw_y += 5 elif button == 5: # down draw_y -= 5 popup.clear() # NOTE DRY violation popup.text = lines_to_text(old_text) + new_text popup.draw_text(x=2, y=draw_y) popup.draw() popup.text = lines_to_text(old_text) elif button == 8: # move the window around (crudely) new_pos = (popup.x+x-popup.width//2, popup.y+y-popup.height//2) popup.win.place(new_pos[0], new_pos[1], popup.width, popup.height, popup.border_width, popup.border) popup.x, popup.y = new_pos # .place() doesn't change these log_test(f"button {button} clicked") except Exception as e: log_test(f"button click error: {e}") popup.win.process_button_click = b_press def enter(*args): try: popup.win.focus(warp=False) log_test("pointer enter") except Exception as e: log_test(f"pointer enter error: {e}") popup.win.process_pointer_enter = enter except Exception as e: log_test(f"repl error: {e}")