Skip to content

Commit

Permalink
#2539 add 'copy-to-clipboard'
Browse files Browse the repository at this point in the history
git-svn-id: https://xpra.org/svn/Xpra/trunk@26492 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed May 28, 2020
1 parent 416ec46 commit a34bad3
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 45 deletions.
135 changes: 91 additions & 44 deletions src/xpra/client/gtk_base/window_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

from gi.repository import Gtk, GLib
from gi.repository import Gtk, Gdk, GLib

from xpra.util import typedict, csv, WORKSPACE_UNSET
from xpra.os_util import bytestostr
Expand All @@ -26,6 +26,49 @@ def x(self):
self.geometry_hints = {}
self.pending_refresh = []

def dict_str(d):
return "\n".join("%s : %s" % (k,v) for k,v in d.items())

def geom_str(geom):
return "%ix%i at %i,%i" % (geom[2], geom[3], geom[0], geom[1])

def hsc(sc):
#make the dict more human readable
ssc = dict((bytestostr(k),v) for k,v in sc.items())
ssc.pop("gravity", None)
return dict_str(ssc)

def get_window_state(w):
state = []
for s in (
"fullscreen", "maximized",
"above", "below", "shaded", "sticky",
"skip-pager", "skip-taskbar",
"iconified",
):
#ie: "skip-pager" -> self.window._skip_pager
if getattr(w, "_%s" % s.replace("-", "_"), False):
state.append(s)
for s in ("modal", ):
fn = getattr(w, "get_%s" % s, None)
if fn and fn():
state.append(s)
return csv(state) or "none"

def get_window_attributes(w):
attr = {}
workspace = w.get_desktop_workspace()
if workspace not in (None, WORKSPACE_UNSET):
attr["workspace"] = workspace
opacity = w.get_opacity()
if opacity<1:
attr["opacity"] = opacity
role = w.get_role()
if role:
attr["role"] = role
#get_type_hint
return dict_str(attr)


class WindowInfo(Gtk.Window):

Expand Down Expand Up @@ -67,7 +110,7 @@ def window_deleted(*_args):
tb.new_row("Button State", self.button_state_label)
#self.group_leader_label = slabel()
#tb.new_row("Group Leader", self.group_leader_label)
tb.new_row("", slabel())
tb.new_row("")
self.gravity_label = slabel()
tb.new_row("Gravity", self.gravity_label)
self.content_type_label = slabel()
Expand All @@ -79,7 +122,7 @@ def window_deleted(*_args):
tb.new_row("Alpha Channel", self.alpha_image)
self.opengl_image = Gtk.Image()
tb.new_row("OpenGL", self.opengl_image)
tb.new_row("", slabel())
tb.new_row("")
self.geometry_label = slabel()
tb.new_row("Geometry", self.geometry_label)
self.outer_geometry_label = slabel()
Expand All @@ -94,14 +137,18 @@ def window_deleted(*_args):
tb.new_row("Maximum Size", self.max_size_label)
self.size_constraints_label = slabel()
tb.new_row("Size Constraints", self.size_constraints_label)
tb.new_row("", slabel())
tb.new_row("")
#backing:
self.backing_size_label = slabel()
tb.new_row("Backing Size", self.backing_size_label)
self.backing_render_size_label = slabel()
tb.new_row("Backing Render Size", self.backing_render_size_label)
self.backing_offsets_label = slabel()
tb.new_row("Backing Offsets", self.backing_offsets_label)
tb.new_row("")
btn = Gtk.Button(label="Copy to clipboard")
btn.connect("clicked", self.copy_to_clipboard)
tb.new_row("", btn)
vbox = Gtk.VBox()
vbox.pack_start(tb.get_table(), True, True, 20)
self.add(vbox)
Expand All @@ -122,44 +169,52 @@ def populate(self):
self.do_populate()
return True

def copy_to_clipboard(self, *_args):
w = self._window
if not w:
return
info = {
"wid" : w._id,
"title" : w.get_title(),
"override-redirect" : w._override_redirect,
"state" : get_window_state(w),
"attributes" : get_window_attributes(w),
"focused" : w._focused,
"buttons" : csv(b for b,s in w.button_state.items() if s) or "none",
"gravity" : GRAVITY_STR.get(w.window_gravity, "invalid"),
"content-type" : w.content_type or "unknown",
"pixel-depth" : w.pixel_depth or 24,
"alpha" : w._window_alpha,
"opengl" : w.is_GL(),
"geometry" : geom_str(list(w._pos)+list(w._size)),
"outer-geometry" : geom_str(list(w.get_position()) + list(w.get_size())),
"inner-geometry" : geom_str(w.get_drawing_area_geometry()),
"offsets" : csv(str(x) for x in (w.window_offset or ())) or "none",
"frame-extents" : csv(w._current_frame_extents or []) or "none",
"max-size" : csv(w.max_window_size),
"size-constraints" : hsc(w.size_constraints),
}
#backing:
b = w._backing
if b:
info.update({
"size" : csv(b.size),
"render-size" : csv(b.render_size),
"backing-offsets" : csv(b.offsets),
})
text = "\n".join("%s=%s" % (k,v) for k,v in info.items())
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clipboard.set_text(text, len(text))

def do_populate(self):
w = self._window
if not w:
return
def dict_str(d):
return "\n".join("%s : %s" % (k,v) for k,v in d.items())
def get_window_state():
state = []
for s in ("fullscreen", "maximized",
"above", "below", "shaded", "sticky",
"skip-pager", "skip-taskbar",
"iconified"):
#ie: "skip-pager" -> self.window._skip_pager
if getattr(w, "_%s" % s.replace("-", "_"), False):
state.append(s)
for s in ("modal", ):
fn = getattr(w, "get_%s" % s, None)
if fn and fn():
state.append(s)
return csv(state) or "none"
def get_attributes():
attr = {}
workspace = w.get_desktop_workspace()
if workspace not in (None, WORKSPACE_UNSET):
attr["workspace"] = workspace
opacity = w.get_opacity()
if opacity<1:
attr["opacity"] = opacity
role = w.get_role()
if role:
attr["role"] = role
#get_type_hint
return dict_str(attr)
self.wid_label.set_text(str(w._id))
self.title_label.set_text(w.get_title())
self.bool_icon(self.or_image, w._override_redirect)
self.state_label.set_text(get_window_state())
self.attributes_label.set_text(get_attributes())
self.state_label.set_text(get_window_state(w))
self.attributes_label.set_text(get_window_attributes(w))
self.bool_icon(self.focus_image, w._focused)
self.button_state_label.set_text(csv(b for b,s in w.button_state.items() if s) or "none")
#self.group_leader_label.set_text(str(w.group_leader))
Expand All @@ -170,22 +225,14 @@ def get_attributes():
self.bool_icon(self.alpha_image, w._window_alpha)
self.bool_icon(self.opengl_image, w.is_GL())
#tells us if this window instance can paint with alpha
self._window_alpha = False
def geom_str(geom):
return "%ix%i at %i,%i" % (geom[2], geom[3], geom[0], geom[1])
geom = list(w._pos)+list(w._size)
self.geometry_label.set_text(geom_str(geom))
geom = list(w.get_position()) + list(w.get_size())
self.outer_geometry_label.set_text(geom_str(geom))
self.inner_geometry_label.set_text(geom_str(w.get_drawing_area_geometry()))
self.offsets_label.set_text(",".join(str(x) for x in (w.window_offset or ())) or "none")
self.offsets_label.set_text(csv(str(x) for x in (w.window_offset or ())) or "none")
self.frame_extents_label.set_text(csv(w._current_frame_extents or []) or "none")
self.max_size_label.set_text(csv(w.max_window_size))
def hsc(sc):
#make the dict more human readable
ssc = dict((bytestostr(k),v) for k,v in sc.items())
ssc.pop("gravity", None)
return dict_str(ssc)
self.size_constraints_label.set_text(hsc(w.size_constraints))
#backing:
b = w._backing
Expand Down
2 changes: 1 addition & 1 deletion src/xpra/gtk_common/gtk_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ def attach(self, widget, i, count=1, xoptions=Gtk.AttachOptions.FILL, yoptions=G
def inc(self):
self.row += 1

def new_row(self, row_label_str, value1, value2=None, label_tooltip=None, **kwargs):
def new_row(self, row_label_str="", value1=None, value2=None, label_tooltip=None, **kwargs):
row_label = label(row_label_str, label_tooltip)
self.add_row(row_label, value1, value2, **kwargs)

Expand Down

0 comments on commit a34bad3

Please sign in to comment.