Fix the drag-and-drop of terminals/text back to pre-port functionality - a real pain this one (gtk2->gtk3)
This commit is contained in:
parent
8b566b9859
commit
d56da596b3
|
@ -8,7 +8,7 @@ import sys
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import gi
|
import gi
|
||||||
from gi.repository import GLib, GObject, Pango, Gtk, Gdk
|
from gi.repository import GLib, GObject, Pango, Gtk, Gdk, cairo
|
||||||
gi.require_version('Vte', '2.91') # vte-0.38 (gnome-3.14)
|
gi.require_version('Vte', '2.91') # vte-0.38 (gnome-3.14)
|
||||||
from gi.repository import Vte
|
from gi.repository import Vte
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -128,7 +128,7 @@ class Terminal(Gtk.VBox):
|
||||||
self.pending_on_vte_size_allocate = False
|
self.pending_on_vte_size_allocate = False
|
||||||
|
|
||||||
self.vte = Vte.Terminal()
|
self.vte = Vte.Terminal()
|
||||||
self.vte._expose_data = None
|
self.vte._draw_data = None
|
||||||
if not hasattr(self.vte, "set_opacity") or \
|
if not hasattr(self.vte, "set_opacity") or \
|
||||||
not hasattr(self.vte, "is_composited"):
|
not hasattr(self.vte, "is_composited"):
|
||||||
self.composite_support = False
|
self.composite_support = False
|
||||||
|
@ -363,18 +363,40 @@ class Terminal(Gtk.VBox):
|
||||||
dsttargets = [("vte", Gtk.TargetFlags.SAME_APP, self.TARGET_TYPE_VTE),
|
dsttargets = [("vte", Gtk.TargetFlags.SAME_APP, self.TARGET_TYPE_VTE),
|
||||||
('text/x-moz-url', 0, 0),
|
('text/x-moz-url', 0, 0),
|
||||||
('_NETSCAPE_URL', 0, 0)]
|
('_NETSCAPE_URL', 0, 0)]
|
||||||
# dsttargets = Gtk.target_list_add_text_targets(dsttargets) # FIXME FOR GTK3
|
'''
|
||||||
# dsttargets = Gtk.target_list_add_uri_targets(dsttargets)
|
The following should work, but on my system it corrupts the returned
|
||||||
|
TargetEntry's in the newdstargets with binary crap, causing "Segmentation
|
||||||
|
fault (core dumped)" when the later drag_dest_set gets called.
|
||||||
|
|
||||||
|
dsttargetlist = Gtk.TargetList.new([])
|
||||||
|
dsttargetlist.add_text_targets(0)
|
||||||
|
dsttargetlist.add_uri_targets(0)
|
||||||
|
dsttargetlist.add_table(dsttargets)
|
||||||
|
|
||||||
|
newdsttargets = Gtk.target_table_new_from_list(dsttargetlist)
|
||||||
|
'''
|
||||||
|
# FIXME: Temporary workaround for the problems with the correct way of doing things
|
||||||
|
dsttargets.extend([('text/plain', 0, 0),
|
||||||
|
('text/plain;charset=utf-8', 0, 0),
|
||||||
|
('TEXT', 0, 0),
|
||||||
|
('STRING', 0, 0),
|
||||||
|
('UTF8_STRING', 0, 0),
|
||||||
|
('COMPOUND_TEXT', 0, 0),
|
||||||
|
('text/uri-list', 0, 0)])
|
||||||
|
# Convert to target entries
|
||||||
|
srcvtetargets = [Gtk.TargetEntry.new(*tgt) for tgt in srcvtetargets]
|
||||||
|
dsttargets = [Gtk.TargetEntry.new(*tgt) for tgt in dsttargets]
|
||||||
|
|
||||||
dbg('Finalised drag targets: %s' % dsttargets)
|
dbg('Finalised drag targets: %s' % dsttargets)
|
||||||
|
|
||||||
# for (widget, mask) in [
|
for (widget, mask) in [
|
||||||
# (self.vte, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.BUTTON3_MASK),
|
(self.vte, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.BUTTON3_MASK),
|
||||||
# (self.titlebar, Gdk.ModifierType.BUTTON1_MASK)]:
|
(self.titlebar, Gdk.ModifierType.BUTTON1_MASK)]:
|
||||||
# widget.drag_source_set(mask, srcvtetargets, Gdk.DragAction.MOVE) # FIXME FOR GTK3
|
widget.drag_source_set(mask, srcvtetargets, Gdk.DragAction.MOVE)
|
||||||
#
|
|
||||||
# self.vte.drag_dest_set(Gtk.DestDefaults.MOTION |
|
self.vte.drag_dest_set(Gtk.DestDefaults.MOTION |
|
||||||
# Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP,
|
Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP,
|
||||||
# dsttargets, Gdk.DragAction.COPY | Gdk.DragAction.MOVE) # FIXME FOR GTK3
|
dsttargets, Gdk.DragAction.COPY | Gdk.DragAction.MOVE)
|
||||||
|
|
||||||
for widget in [self.vte, self.titlebar]:
|
for widget in [self.vte, self.titlebar]:
|
||||||
widget.connect('drag-begin', self.on_drag_begin, self)
|
widget.connect('drag-begin', self.on_drag_begin, self)
|
||||||
|
@ -919,29 +941,28 @@ class Terminal(Gtk.VBox):
|
||||||
|
|
||||||
def on_drag_begin(self, widget, drag_context, _data):
|
def on_drag_begin(self, widget, drag_context, _data):
|
||||||
"""Handle the start of a drag event"""
|
"""Handle the start of a drag event"""
|
||||||
widget.drag_source_set_icon_pixbuf(util.widget_pixbuf(self, 512))
|
Gtk.drag_set_icon_pixbuf(drag_context, util.widget_pixbuf(self, 512), 0, 0)
|
||||||
|
|
||||||
def on_drag_data_get(self, _widget, _drag_context, selection_data, info,
|
def on_drag_data_get(self, _widget, _drag_context, selection_data, info,
|
||||||
_time, data):
|
_time, data):
|
||||||
"""I have no idea what this does, drag and drop is a mystery. sorry."""
|
"""I have no idea what this does, drag and drop is a mystery. sorry."""
|
||||||
selection_data.set('vte', info,
|
selection_data.set(Gdk.atom_intern('vte', False), info,
|
||||||
str(data.terminator.terminals.index(self)))
|
str(data.terminator.terminals.index(self)))
|
||||||
|
|
||||||
def on_drag_motion(self, widget, drag_context, x, y, _time, _data):
|
def on_drag_motion(self, widget, drag_context, x, y, _time, _data):
|
||||||
"""*shrug*"""
|
"""*shrug*"""
|
||||||
if not drag_context.targets == ['vte'] and \
|
if not drag_context.list_targets() == [Gdk.atom_intern('vte', False)] and \
|
||||||
(Gtk.targets_include_text(drag_context.targets) or \
|
(Gtk.targets_include_text(drag_context.list_targets()) or \
|
||||||
Gtk.targets_include_uri(drag_context.targets)):
|
Gtk.targets_include_uri(drag_context.list_targets())):
|
||||||
# copy text from another widget
|
# copy text from another widget
|
||||||
return
|
return
|
||||||
srcwidget = drag_context.get_source_widget()
|
srcwidget = Gtk.drag_get_source_widget(drag_context)
|
||||||
if(isinstance(srcwidget, Gtk.EventBox) and
|
if(isinstance(srcwidget, Gtk.EventBox) and
|
||||||
srcwidget == self.titlebar) or widget == srcwidget:
|
srcwidget == self.titlebar) or widget == srcwidget:
|
||||||
# on self
|
# on self
|
||||||
return
|
return
|
||||||
|
|
||||||
alloc = widget.get_allocation()
|
alloc = widget.get_allocation()
|
||||||
rect = (0, 0, alloc.width, alloc.height)
|
|
||||||
|
|
||||||
if self.config['use_theme_colors']:
|
if self.config['use_theme_colors']:
|
||||||
color = self.vte.get_style_context().get_color(Gtk.StateType.NORMAL) # VERIFY FOR GTK3 as above
|
color = self.vte.get_style_context().get_color(Gtk.StateType.NORMAL) # VERIFY FOR GTK3 as above
|
||||||
|
@ -970,24 +991,23 @@ class Terminal(Gtk.VBox):
|
||||||
coord = (bottomleft, bottomright, middleright , middleleft)
|
coord = (bottomleft, bottomright, middleright , middleleft)
|
||||||
|
|
||||||
#here, we define some widget internal values
|
#here, we define some widget internal values
|
||||||
widget._expose_data = { 'color': color, 'coord' : coord }
|
widget._draw_data = { 'color': color, 'coord' : coord }
|
||||||
#redraw by forcing an event
|
#redraw by forcing an event
|
||||||
connec = widget.connect_after('expose-event', self.on_expose_event)
|
connec = widget.connect_after('draw', self.on_draw)
|
||||||
widget.window.invalidate_rect(rect, True)
|
widget.queue_draw_area(0, 0, alloc.width, alloc.height)
|
||||||
widget.window.process_updates(True)
|
widget.get_window().process_updates(True)
|
||||||
#finaly reset the values
|
#finaly reset the values
|
||||||
widget.disconnect(connec)
|
widget.disconnect(connec)
|
||||||
widget._expose_data = None
|
widget._draw_data = None
|
||||||
|
|
||||||
def on_expose_event(self, widget, _event):
|
def on_draw(self, widget, context):
|
||||||
"""Handle an expose event while dragging"""
|
"""Handle an expose event while dragging"""
|
||||||
if not widget._expose_data:
|
if not widget._draw_data:
|
||||||
return(False)
|
return(False)
|
||||||
|
|
||||||
color = widget._expose_data['color']
|
color = widget._draw_data['color']
|
||||||
coord = widget._expose_data['coord']
|
coord = widget._draw_data['coord']
|
||||||
|
|
||||||
context = widget.window.cairo_create()
|
|
||||||
context.set_source_rgba(color.red, color.green, color.blue, 0.5)
|
context.set_source_rgba(color.red, color.green, color.blue, 0.5)
|
||||||
if len(coord) > 0 :
|
if len(coord) > 0 :
|
||||||
context.move_to(coord[len(coord)-1][0], coord[len(coord)-1][1])
|
context.move_to(coord[len(coord)-1][0], coord[len(coord)-1][1])
|
||||||
|
@ -1001,11 +1021,11 @@ class Terminal(Gtk.VBox):
|
||||||
_info, _time, data):
|
_info, _time, data):
|
||||||
"""Something has been dragged into the terminal. Handle it as either a
|
"""Something has been dragged into the terminal. Handle it as either a
|
||||||
URL or another terminal."""
|
URL or another terminal."""
|
||||||
dbg('drag data received of type: %s' % selection_data.type)
|
dbg('drag data received of type: %s' % (selection_data.get_data_type()))
|
||||||
if Gtk.targets_include_text(drag_context.targets) or \
|
if Gtk.targets_include_text(drag_context.list_targets()) or \
|
||||||
Gtk.targets_include_uri(drag_context.targets):
|
Gtk.targets_include_uri(drag_context.list_targets()):
|
||||||
# copy text to destination
|
# copy text to destination
|
||||||
txt = selection_data.data.strip(' ')
|
txt = selection_data.get_data().strip(' ')
|
||||||
if txt[0:7] == 'file://':
|
if txt[0:7] == 'file://':
|
||||||
txt = "'%s'" % urllib.unquote(txt[7:])
|
txt = "'%s'" % urllib.unquote(txt[7:])
|
||||||
else:
|
else:
|
||||||
|
@ -1014,8 +1034,8 @@ class Terminal(Gtk.VBox):
|
||||||
term.feed(txt)
|
term.feed(txt)
|
||||||
return
|
return
|
||||||
|
|
||||||
widgetsrc = data.terminator.terminals[int(selection_data.data)]
|
widgetsrc = data.terminator.terminals[int(selection_data.get_data())]
|
||||||
srcvte = drag_context.get_source_widget()
|
srcvte = Gtk.drag_get_source_widget(drag_context)
|
||||||
#check if computation requireds
|
#check if computation requireds
|
||||||
if (isinstance(srcvte, Gtk.EventBox) and
|
if (isinstance(srcvte, Gtk.EventBox) and
|
||||||
srcvte == self.titlebar) or srcvte == widget:
|
srcvte == self.titlebar) or srcvte == widget:
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk, Gdk
|
||||||
|
import cairo
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -142,11 +143,9 @@ def shell_lookup():
|
||||||
|
|
||||||
def widget_pixbuf(widget, maxsize=None):
|
def widget_pixbuf(widget, maxsize=None):
|
||||||
"""Generate a pixbuf of a widget"""
|
"""Generate a pixbuf of a widget"""
|
||||||
pixmap = widget.get_snapshot()
|
# FIXME: Can this be changed from using "import cairo" to "from gi.repository import cairo"?
|
||||||
(width, height) = pixmap.get_size()
|
window = widget.get_window()
|
||||||
pixbuf = GdkPixbuf.Pixbuf(GdkPixbuf.Colorspace.RGB, False, 8, width, height)
|
width, height = window.get_width(), window.get_height()
|
||||||
pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, width,
|
|
||||||
height)
|
|
||||||
|
|
||||||
longest = max(width, height)
|
longest = max(width, height)
|
||||||
|
|
||||||
|
@ -156,8 +155,18 @@ def widget_pixbuf(widget, maxsize=None):
|
||||||
if not maxsize or (width * factor) > width or (height * factor) > height:
|
if not maxsize or (width * factor) > width or (height * factor) > height:
|
||||||
factor = 1
|
factor = 1
|
||||||
|
|
||||||
scaledpixbuf = pixbuf.scale_simple(int(width * factor), int(height * factor), GdkPixbuf.InterpType.BILINEAR)
|
preview_width, preview_height = int(width * factor), int(height * factor)
|
||||||
|
|
||||||
|
preview_surface = Gdk.Window.create_similar_surface(window,
|
||||||
|
cairo.CONTENT_COLOR, preview_width, preview_height)
|
||||||
|
|
||||||
|
cairo_context = cairo.Context(preview_surface)
|
||||||
|
cairo_context.scale(factor, factor)
|
||||||
|
Gdk.cairo_set_source_window(cairo_context, window, 0, 0)
|
||||||
|
cairo_context.paint()
|
||||||
|
|
||||||
|
scaledpixbuf = Gdk.pixbuf_get_from_surface(preview_surface, 0, 0, preview_width, preview_height);
|
||||||
|
|
||||||
return(scaledpixbuf)
|
return(scaledpixbuf)
|
||||||
|
|
||||||
def get_config_dir():
|
def get_config_dir():
|
||||||
|
|
Loading…
Reference in New Issue