Skip to content

Commit fa86c23

Browse files
authored
Add files via upload
1 parent 449ba9c commit fa86c23

1 file changed

Lines changed: 125 additions & 3 deletions

File tree

BlackGlass.py

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class LimitedScrolledText(scrolledtext.ScrolledText):
4545
def __init__(self, master=None, max_lines=1000, **kw):
4646
super().__init__(master, **kw)
4747
self.max_lines = max_lines
48+
# Hide the built-in vertical scrollbar while keeping scroll functionality.
49+
# ScrolledText stores it as self.vbar; setting width=0 makes it invisible.
50+
self.vbar.config(width=0, takefocus=False)
51+
self.vbar.pack_forget()
4852

4953
def insert(self, index, chars, *args):
5054
super().insert(index, chars, *args)
@@ -979,6 +983,34 @@ class KickUser(BaseMessage):
979983
registerMessage(KickUser)
980984
# --- END KICKUSER PACKET ---
981985

986+
# --- INSTANT MESSAGE PACKETS ---
987+
class ImprovedInstantMessage(BaseMessage):
988+
"""
989+
Received from the simulator when another avatar sends us a private IM.
990+
Dialog types: 0 = plain IM, 9 = group notice, 19 = friendship offer, etc.
991+
"""
992+
name = "ImprovedInstantMessage"; id = 254; freq = 2; trusted = True; zero_coded = True
993+
blocks = [("AgentData", 1), ("MessageBlock", 1)]
994+
structure = {
995+
"AgentData": [("AgentID", "LLUUID"), ("SessionID", "LLUUID")],
996+
"MessageBlock": [
997+
("FromGroup", "BOOL"),
998+
("ToAgentID", "LLUUID"),
999+
("ParentEstateID", "U32"),
1000+
("RegionID", "LLUUID"),
1001+
("Position", "LLVector3"),
1002+
("Offline", "U8"),
1003+
("Dialog", "U8"),
1004+
("ID", "LLUUID"),
1005+
("Timestamp", "U32"),
1006+
("FromAgentName", "Variable", 1),
1007+
("Message", "Variable", 2),
1008+
("BinaryBucket", "Variable", 2),
1009+
]
1010+
}
1011+
registerMessage(ImprovedInstantMessage)
1012+
# --- END INSTANT MESSAGE PACKETS ---
1013+
9821014

9831015
# ==========================================
9841016
# SECTION 5: PACKET HANDLING (packet.py)
@@ -2984,9 +3016,7 @@ def _fetch_parcel_name_task(self, parcel_uuid):
29843016
req = urllib.request.Request(
29853017
url,
29863018
headers={
2987-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
2988-
'AppleWebKit/537.36 (KHTML, like Gecko) '
2989-
'Chrome/120.0.0.0 Safari/537.36',
3019+
'User-Agent': 'BlackGlass',
29903020
'Accept': 'text/html'
29913021
}
29923022
)
@@ -4754,6 +4784,7 @@ def _create_widgets(self):
47544784
insertbackground='white',
47554785
relief=tk.FLAT, highlightthickness=1, highlightbackground='#444444')
47564786
self.chat_display.grid(row=0, column=0, sticky='nsew', padx=(0, 0))
4787+
self.chat_display.bind("<Button-3>", self._show_chat_context_menu)
47574788

47584789
# --- FIX: Configure tag for gray speaker name ---
47594790
self.chat_display.tag_config('speaker_name', foreground='#AAAAAA')
@@ -4806,6 +4837,7 @@ def _create_widgets(self):
48064837
insertbackground='white', relief=tk.FLAT, highlightthickness=1, highlightbackground='#555555')
48074838
self.message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5))
48084839
self.message_entry.bind("<Return>", self.send_message_event)
4840+
self.message_entry.bind("<Button-3>", self._show_entry_context_menu)
48094841

48104842
self.send_button = ttk.Button(input_frame, text="Send", command=self.send_message, style='BlackGlass.TButton')
48114843
self.send_button.pack(side=tk.RIGHT)
@@ -5708,6 +5740,96 @@ def _show_teleport_offer(self, offer_data):
57085740
self._update_status("Teleport offer declined.")
57095741
self._append_notification(f"[INFO] Teleport offer to {region_name} declined.")
57105742

5743+
# ------------------------------------------------------------------ #
5744+
# Right-click context menus #
5745+
# ------------------------------------------------------------------ #
5746+
5747+
def _make_context_menu(self):
5748+
"""Create a themed popup menu matching the BlackGlass dark style."""
5749+
menu = tk.Menu(self, tearoff=0,
5750+
bg='#2C2C2C', fg='#E0E0E0',
5751+
activebackground='#444444', activeforeground='#FFFFFF',
5752+
relief=tk.FLAT, bd=1)
5753+
return menu
5754+
5755+
def _show_chat_context_menu(self, event):
5756+
"""Right-click menu for the read-only chat display (copy / select-all)."""
5757+
menu = self._make_context_menu()
5758+
5759+
def do_copy():
5760+
try:
5761+
selected = self.chat_display.get(tk.SEL_FIRST, tk.SEL_LAST)
5762+
self.master.clipboard_clear()
5763+
self.master.clipboard_append(selected)
5764+
except tk.TclError:
5765+
pass # Nothing selected
5766+
5767+
def do_select_all():
5768+
self.chat_display.tag_add(tk.SEL, '1.0', tk.END)
5769+
self.chat_display.mark_set(tk.INSERT, '1.0')
5770+
self.chat_display.see(tk.INSERT)
5771+
5772+
menu.add_command(label='Copy', command=do_copy)
5773+
menu.add_separator()
5774+
menu.add_command(label='Select All', command=do_select_all)
5775+
5776+
try:
5777+
menu.tk_popup(event.x_root, event.y_root)
5778+
finally:
5779+
menu.grab_release()
5780+
5781+
def _show_entry_context_menu(self, event):
5782+
"""Right-click menu for the message Entry (cut / copy / paste / select-all)."""
5783+
menu = self._make_context_menu()
5784+
5785+
def do_cut():
5786+
try:
5787+
selected = self.message_entry.selection_get()
5788+
self.master.clipboard_clear()
5789+
self.master.clipboard_append(selected)
5790+
self.message_entry.delete(tk.SEL_FIRST, tk.SEL_LAST)
5791+
except tk.TclError:
5792+
pass
5793+
5794+
def do_copy():
5795+
try:
5796+
selected = self.message_entry.selection_get()
5797+
self.master.clipboard_clear()
5798+
self.master.clipboard_append(selected)
5799+
except tk.TclError:
5800+
pass
5801+
5802+
def do_paste():
5803+
try:
5804+
text = self.master.clipboard_get()
5805+
# Insert at cursor, replacing any active selection
5806+
try:
5807+
self.message_entry.delete(tk.SEL_FIRST, tk.SEL_LAST)
5808+
except tk.TclError:
5809+
pass
5810+
self.message_entry.insert(tk.INSERT, text)
5811+
except tk.TclError:
5812+
pass
5813+
5814+
def do_select_all():
5815+
self.message_entry.select_range(0, tk.END)
5816+
self.message_entry.icursor(tk.END)
5817+
5818+
menu.add_command(label='Cut', command=do_cut)
5819+
menu.add_command(label='Copy', command=do_copy)
5820+
menu.add_command(label='Paste', command=do_paste)
5821+
menu.add_separator()
5822+
menu.add_command(label='Select All', command=do_select_all)
5823+
5824+
# Focus the entry so clipboard operations target it
5825+
self.message_entry.focus_set()
5826+
try:
5827+
menu.tk_popup(event.x_root, event.y_root)
5828+
finally:
5829+
menu.grab_release()
5830+
5831+
# ------------------------------------------------------------------ #
5832+
57115833
def send_message_event(self, event):
57125834
self.send_message()
57135835
return "break"

0 commit comments

Comments
 (0)