xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #2390: gtk3-focus.patch

File gtk3-focus.patch, 14.8 KB (added by Antoine Martin, 20 months ago)

work in progress patch

  • xpra/client/gl/gtk3/gl_client_window.py

     
    44# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
    55# later version. See the file COPYING for details.
    66
    7 from xpra.client.gtk3.client_window import ClientWindow
     7from xpra.client.gtk3.gtk3_client_window import GTK3ClientWindow
    88from xpra.client.gl.gtk_base.gl_client_window_common import GLClientWindowCommon
    99from xpra.log import Logger
    1010
     
    1111log = Logger("opengl", "window")
    1212
    1313
    14 class GLClientWindowBase(GLClientWindowCommon, ClientWindow):
     14class GLClientWindowBase(GLClientWindowCommon, GTK3ClientWindow):
    1515
    1616    def set_alpha(self):
    17         ClientWindow.set_alpha(self)
     17        GTK3ClientWindow.set_alpha(self)
    1818        rgb_formats = self._client_properties.get("encodings.rgb_formats", [])
    1919        GLClientWindowCommon.add_rgb_formats(self, rgb_formats)
    2020
    2121    def do_configure_event(self, event):
    2222        log("GL do_configure_event(%s)", event)
    23         ClientWindow.do_configure_event(self, event)
     23        GTK3ClientWindow.do_configure_event(self, event)
    2424        self._backing.paint_screen = True
    2525
    2626    def destroy(self):
    2727        self.remove_backing()
    28         ClientWindow.destroy(self)
     28        GTK3ClientWindow.destroy(self)
    2929
    3030    def new_backing(self, bw, bh):
    31         widget = ClientWindow.new_backing(self, bw, bh)
     31        widget = GTK3ClientWindow.new_backing(self, bw, bh)
    3232        if self.drawing_area:
    3333            self.remove(self.drawing_area)
    3434        self.init_widget_events(widget)
  • xpra/client/gl/gtk3/gtkgl_client_window.py

     
    33# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
    44# later version. See the file COPYING for details.
    55
     6from xpra.gtk_common import gi_init
     7from gi.repository import GObject               #@UnresolvedImport @UnusedImport
     8
    69from xpra.client.gl.gtk3.gl_client_window import GLClientWindowBase
    710from xpra.client.gl.gtk3.gl_window_backing import GLPixmapBacking
    811from xpra.client.gl.gtk_base.gtkgl_check import check_support
     12
    913assert check_support
     14assert gi_init
    1015
    11 
    1216class GLClientWindow(GLClientWindowBase):
    1317
     18    __gsignals__ = GLClientWindowBase.__common_gsignals__
     19
    1420    def get_backing_class(self):
    1521        return GLPixmapBacking
     22
     23GObject.type_register(GLClientWindow)
  • xpra/client/gl/gtk3/nativegl_client_window.py

     
    33# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
    44# later version. See the file COPYING for details.
    55
     6from xpra.gtk_common import gi_init
     7from gi.repository import GObject               #@UnresolvedImport @UnusedImport
     8
    69from xpra.client.gl.gtk3.gl_client_window import GLClientWindowBase
    710from xpra.client.gl.gtk_base.gl_drawing_area import GLDrawingArea, GLContext
    811
     
    912def check_support(force_enable=False, check_colormap=False):
    1013    return GLContext().check_support(force_enable)  #pylint: disable=not-callable
    1114
     15assert gi_init
    1216
     17
    1318class GLClientWindow(GLClientWindowBase):
     19    __gsignals__ = GLClientWindowBase.__common_gsignals__
    1420
    1521    def get_backing_class(self):
    1622        return GLDrawingArea
     23
     24GObject.type_register(GLClientWindow)
  • xpra/client/gtk2/gtk2_window_base.py

     
    4848    #add GTK focus workaround so we will get focus events
    4949    #even when we grab the keyboard:
    5050    __common_gsignals__ = GTKClientWindowBase.__common_gsignals__
    51     __common_gsignals__.update({
    52                                 "xpra-focus-out-event"  : one_arg_signal,
    53                                 "xpra-focus-in-event"   : one_arg_signal,
    54                                 })
    5551
    5652    OR_TYPE_HINTS       = GTK2_OR_TYPE_HINTS
    5753    NAME_TO_HINT        = WINDOW_NAME_TO_HINT
  • xpra/client/gtk3/client_window.py

     
    11# This file is part of Xpra.
    2 # Copyright (C) 2011 Serviware (Arthur Huillet, <ahuillet@serviware.com>)
    32# Copyright (C) 2010-2019 Antoine Martin <antoine@xpra.org>
    43# Copyright (C) 2008, 2010 Nathaniel Smith <njs@pobox.com>
    54# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
     
    76
    87from xpra.gtk_common import gi_init
    98from gi.repository import GObject               #@UnresolvedImport @UnusedImport
    10 from gi.repository import Gtk                   #@UnresolvedImport @UnusedImport
    11 from gi.repository import Gdk                   #@UnresolvedImport @UnusedImport
    129
    1310from xpra.client.gtk3.cairo_backing import CairoBacking
    14 from xpra.client.gtk_base.gtk_client_window_base import GTKClientWindowBase, HAS_X11_BINDINGS
    15 from xpra.gtk_common.gtk_util import WINDOW_NAME_TO_HINT, BUTTON_MASK
    16 from xpra.os_util import bytestostr
    17 from xpra.log import Logger
     11from xpra.client.gtk3.gtk3_client_window import GTK3ClientWindow
    1812
    19 log = Logger("gtk", "window")
    20 paintlog = Logger("paint")
    21 metalog = Logger("metadata")
    22 
    23 
    2413assert gi_init
    25 GTK3_OR_TYPE_HINTS = (Gdk.WindowTypeHint.DIALOG,
    26                       Gdk.WindowTypeHint.MENU,
    27                       Gdk.WindowTypeHint.TOOLBAR,
    28                       #Gdk.WindowTypeHint.SPLASHSCREEN,
    29                       #Gdk.WindowTypeHint.UTILITY,
    30                       #Gdk.WindowTypeHint.DOCK,
    31                       #Gdk.WindowTypeHint.DESKTOP,
    32                       Gdk.WindowTypeHint.DROPDOWN_MENU,
    33                       Gdk.WindowTypeHint.POPUP_MENU,
    34                       Gdk.WindowTypeHint.TOOLTIP,
    35                       #Gdk.WindowTypeHint.NOTIFICATION,
    36                       Gdk.WindowTypeHint.COMBO,
    37                       Gdk.WindowTypeHint.DND)
    3814
    39 
    4015"""
    41 GTK3 version of the ClientWindow class
     16GTK3 window painted with cairo
    4217"""
    43 class ClientWindow(GTKClientWindowBase):
     18class ClientWindow(GTK3ClientWindow):
    4419
    45     __gsignals__ = GTKClientWindowBase.__common_gsignals__
     20    __gsignals__ = GTK3ClientWindow.__common_gsignals__
    4621
    47 
    48     BUTTON_MASK         = BUTTON_MASK
    49     OR_TYPE_HINTS       = GTK3_OR_TYPE_HINTS
    50     NAME_TO_HINT        = WINDOW_NAME_TO_HINT
    51 
    52     WINDOW_STATE_FULLSCREEN = Gdk.WindowState.FULLSCREEN
    53     WINDOW_STATE_MAXIMIZED  = Gdk.WindowState.MAXIMIZED
    54     WINDOW_STATE_ICONIFIED  = Gdk.WindowState.ICONIFIED
    55     WINDOW_STATE_ABOVE      = Gdk.WindowState.ABOVE
    56     WINDOW_STATE_BELOW      = Gdk.WindowState.BELOW
    57     WINDOW_STATE_STICKY     = Gdk.WindowState.STICKY
    58 
    59 
    60     def do_init_window(self, window_type):
    61         Gtk.Window.__init__(self, type = window_type)
    62 
    63     def init_drawing_area(self):
    64         GTKClientWindowBase.init_drawing_area(self)
    65         self.drawing_area.connect("draw", self.drawing_area_draw)
    66 
    6722    def get_backing_class(self):
    6823        return CairoBacking
    6924
    70 
    71     def xget_u32_property(self, target, name):
    72         if HAS_X11_BINDINGS:
    73             return GTKClientWindowBase.xget_u32_property(self, target, name)
    74         #pure Gdk lookup:
    75         try:
    76             name_atom = Gdk.Atom.intern(name, False)
    77             type_atom = Gdk.Atom.intern("CARDINAL", False)
    78             prop = Gdk.property_get(target, name_atom, type_atom, 0, 9999, False)
    79             if not prop or len(prop)!=3 or len(prop[2])!=1:
    80                 return  None
    81             metalog("xget_u32_property(%s, %s)=%s", target, name, prop[2][0])
    82             return prop[2][0]
    83         except Exception as e:
    84             metalog.error("xget_u32_property error on %s / %s: %s", target, name, e)
    85 
    86     def is_mapped(self):
    87         return self.get_mapped()
    88 
    89     def get_drawing_area_geometry(self):
    90         gdkwindow = self.drawing_area.get_window()
    91         x, y = gdkwindow.get_origin()[1:]
    92         w, h = self.get_size()
    93         return (x, y, w, h)
    94 
    95     def apply_geometry_hints(self, hints):
    96         """ we convert the hints as a dict into a gdk.Geometry + gdk.WindowHints """
    97         wh = Gdk.WindowHints
    98         name_to_hint = {"maximum-size"  : wh.MAX_SIZE,
    99                         "max_width"     : wh.MAX_SIZE,
    100                         "max_height"    : wh.MAX_SIZE,
    101                         "minimum-size"  : wh.MIN_SIZE,
    102                         "min_width"     : wh.MIN_SIZE,
    103                         "min_height"    : wh.MIN_SIZE,
    104                         "base-size"     : wh.BASE_SIZE,
    105                         "base_width"    : wh.BASE_SIZE,
    106                         "base_height"   : wh.BASE_SIZE,
    107                         "increment"     : wh.RESIZE_INC,
    108                         "width_inc"     : wh.RESIZE_INC,
    109                         "height_inc"    : wh.RESIZE_INC,
    110                         "min_aspect_ratio"  : wh.ASPECT,
    111                         "max_aspect_ratio"  : wh.ASPECT,
    112                         }
    113         #these fields can be copied directly to the gdk.Geometry as ints:
    114         INT_FIELDS= ["min_width",    "min_height",
    115                         "max_width",    "max_height",
    116                         "base_width",   "base_height",
    117                         "width_inc",    "height_inc"]
    118         ASPECT_FIELDS = {
    119                         "min_aspect_ratio"  : "min_aspect",
    120                         "max_aspect_ratio"  : "max_aspect",
    121                          }
    122         geom = Gdk.Geometry()
    123         mask = 0
    124         for k,v in hints.items():
    125             k = bytestostr(k)
    126             if k in INT_FIELDS:
    127                 setattr(geom, k, v)
    128                 mask |= int(name_to_hint.get(k, 0))
    129             elif k in ASPECT_FIELDS:
    130                 field = ASPECT_FIELDS.get(k)
    131                 setattr(geom, field, float(v))
    132                 mask |= int(name_to_hint.get(k, 0))
    133         gdk_hints = Gdk.WindowHints(mask)
    134         metalog("apply_geometry_hints(%s) geometry=%s, hints=%s", hints, geom, gdk_hints)
    135         self.set_geometry_hints(None, geom, gdk_hints)
    136 
    137     def queue_draw_area(self, x, y, width, height):
    138         window = self.get_window()
    139         if not window:
    140             log.warn("Warning: ignoring draw packet,")
    141             log.warn(" received for a window which is not realized yet or gone already")
    142             return
    143         rect = Gdk.Rectangle()
    144         rect.x = x
    145         rect.y = y
    146         rect.width = width
    147         rect.height = height
    148         self.drawing_area.get_window().invalidate_rect(rect, False)
    149 
    150     def do_draw(self, context):
    151         paintlog("do_draw(%s)", context)
    152         Gtk.Window.do_draw(self, context)
    153 
    154     def drawing_area_draw(self, widget, context):
    155         paintlog("drawing_area_draw(%s, %s)", widget, context)
    156         backing = self._backing
    157         if self.get_mapped() and backing:
    158             self.paint_backing_offset_border(backing, context)
    159             self.clip_to_backing(backing, context)
    160             backing.cairo_draw(context)
    161         self.cairo_paint_border(context, None)
    162         if not self._client.server_ok():
    163             self.paint_spinner(context)
    164 
    165 
    16625GObject.type_register(ClientWindow)
  • xpra/client/gtk3/gtk3_client_window.py

     
    1010from gi.repository import Gtk                   #@UnresolvedImport @UnusedImport
    1111from gi.repository import Gdk                   #@UnresolvedImport @UnusedImport
    1212
    13 from xpra.client.gtk3.cairo_backing import CairoBacking
    1413from xpra.client.gtk_base.gtk_client_window_base import GTKClientWindowBase, HAS_X11_BINDINGS
    1514from xpra.gtk_common.gtk_util import WINDOW_NAME_TO_HINT, BUTTON_MASK
    1615from xpra.os_util import bytestostr
     
    4039"""
    4140GTK3 version of the ClientWindow class
    4241"""
    43 class ClientWindow(GTKClientWindowBase):
     42class GTK3ClientWindow(GTKClientWindowBase):
    4443
    45     __gsignals__ = GTKClientWindowBase.__common_gsignals__
    46 
    47 
    4844    BUTTON_MASK         = BUTTON_MASK
    4945    OR_TYPE_HINTS       = GTK3_OR_TYPE_HINTS
    5046    NAME_TO_HINT        = WINDOW_NAME_TO_HINT
     
    6561        self.drawing_area.connect("draw", self.drawing_area_draw)
    6662
    6763    def get_backing_class(self):
    68         return CairoBacking
     64        raise NotImplementedError()
    6965
    7066
    7167    def xget_u32_property(self, target, name):
     
    161157        self.cairo_paint_border(context, None)
    162158        if not self._client.server_ok():
    163159            self.paint_spinner(context)
    164 
    165 
    166 GObject.type_register(ClientWindow)
  • xpra/client/gtk_base/gtk_client_window_base.py

     
    2323    MOVERESIZE_SIZE_LEFT, MOVERESIZE_MOVE,
    2424    )
    2525from xpra.gtk_common.gobject_compat import import_gtk, import_gdk, import_cairo, is_gtk3
    26 from xpra.gtk_common.gobject_util import no_arg_signal
     26from xpra.gtk_common.gobject_util import no_arg_signal, one_arg_signal
    2727from xpra.gtk_common.gtk_util import (
    2828    get_xwindow, get_pixbuf_from_data, get_default_root_window,
    2929    is_realized, display_get_default, drag_status,
     
    190190
    191191    __common_gsignals__ = {
    192192        "state-updated"         : no_arg_signal,
     193        "xpra-focus-out-event"  : one_arg_signal,
     194        "xpra-focus-in-event"   : one_arg_signal,
    193195        }
    194196
    195197    #maximum size of the actual window:
     
    384386    def do_init_focus(self):
    385387        #hook up the X11 gdk event notifications so we can get focus-out when grabs are active:
    386388        if POSIX and not OSX:
     389            gdk_win = self.get_window()
    387390            try:
     391                xid = get_xwindow(gdk_win)
     392                with xlog:
     393                    X11Window.selectFocusChange(xid)
    388394                from xpra.x11.gtk_x11.gdk_bindings import add_event_receiver
    389395            except ImportError as e:
    390396                log("do_init_focus()", exc_info=True)
     
    393399            else:
    394400                self._focus_latest = None
    395401                grablog("adding event receiver so we can get FocusIn and FocusOut events whilst grabbing the keyboard")
    396                 add_event_receiver(self.get_window(), self)
     402                add_event_receiver(gdk_win, self)
    397403        #other platforms should bet getting regular focus events instead:
    398404        def focus_in(_window, event):
    399405            focuslog("focus-in-event for wid=%s", self._id)