Skip to content

Commit

Permalink
#2243: replace many None dereference bugs with default values or plac…
Browse files Browse the repository at this point in the history
…eholders: dpi, mouse position, transparency support check, icon theme is MIA, keymap cannot be queried?, better to call Gtk.init() early, root window size, X11 display check, etc

git-svn-id: https://xpra.org/svn/Xpra/trunk@22239 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Apr 1, 2019
1 parent 97cb839 commit 2a52f27
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 37 deletions.
18 changes: 13 additions & 5 deletions src/xpra/client/gtk3/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
gi.require_version('Gdk', '3.0') #@UndefinedVariable
from gi.repository import GObject #@UnresolvedImport
from gi.repository import Gdk #@UnresolvedImport
from gi.repository import GLib #@UnresolvedImport

from xpra.os_util import OSX, POSIX
from xpra.os_util import OSX
from xpra.gtk_common.gobject_compat import register_os_signals
from xpra.client.gtk_base.gtk_client_base import GTKXpraClient
from xpra.client.gtk3.client_window import ClientWindow
Expand Down Expand Up @@ -47,18 +46,24 @@ def get_notifier_classes(self):
log.warn(" %s", e)
return ncs

def get_screen_resolution(self):
screen = Gdk.Screen.get_default()
if not screen:
#wayland?
return -1
return screen.get_resolution()

def get_xdpi(self):
xdpi = get_xdpi()
if xdpi>0:
return xdpi
return Gdk.Screen.get_default().get_resolution()
return self.get_screen_resolution()

def get_ydpi(self):
ydpi = get_ydpi()
if ydpi>0:
return ydpi
return Gdk.Screen.get_default().get_resolution()
return self.get_screen_resolution()


def get_tray_menu_helper_class(self):
Expand All @@ -68,7 +73,10 @@ def get_tray_menu_helper_class(self):

def get_mouse_position(self):
#with GTK3, we can get None values!
p = self.get_root_window().get_pointer()[-3:-1]
root = self.get_root_window()
if not root:
return -1, -1
p = root.get_pointer()[-3:-1]
return self.sp(p[0] or 0, p[1] or 0)


Expand Down
48 changes: 29 additions & 19 deletions src/xpra/client/gtk_base/gtk_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
updict, pver, iround, flatten_dict, envbool, repr_ellipsized, csv, first_time,
DEFAULT_METADATA_SUPPORTED, XPRA_OPENGL_NOTIFICATION_ID,
)
from xpra.os_util import bytestostr, strtobytes, hexstr, monotonic_time, WIN32, OSX, POSIX
from xpra.os_util import (
bytestostr, strtobytes, hexstr, monotonic_time,
WIN32, OSX, POSIX, is_Wayland,
)
from xpra.simple_stats import std_unit
from xpra.exit_codes import EXIT_PASSWORD_REQUIRED
from xpra.scripts.config import TRUE_OPTIONS, FALSE_OPTIONS
Expand Down Expand Up @@ -673,7 +676,10 @@ def get_mouse_position(self):
return self.cp(p[0], p[1])

def get_current_modifiers(self):
modifiers_mask = self.get_root_window().get_pointer()[-1]
root = self.get_root_window()
if root is None:
return ()
modifiers_mask = root.get_pointer()[-1]
return self.mask_to_names(modifiers_mask)


Expand All @@ -685,22 +691,23 @@ def make_hello(self):
#tell the server which icons GTK can use
#so it knows when it should supply one as fallback
it = icon_theme_get_default()
#this would add our bundled icon directory
#to the search path, but I don't think we have
#any extra icons that matter in there:
#from xpra.platform.paths import get_icon_dir
#d = get_icon_dir()
#if d not in it.get_search_path():
# it.append_search_path(d)
# it.rescan_if_needed()
log("default icon theme: %s", it)
log("icon search path: %s", it.get_search_path())
log("contexts: %s", it.list_contexts())
icons = []
for context in it.list_contexts():
icons += it.list_icons(context)
log("icons: %s", icons)
capabilities["theme.default.icons"] = tuple(set(icons))
if it:
#this would add our bundled icon directory
#to the search path, but I don't think we have
#any extra icons that matter in there:
#from xpra.platform.paths import get_icon_dir
#d = get_icon_dir()
#if d not in it.get_search_path():
# it.append_search_path(d)
# it.rescan_if_needed()
log("default icon theme: %s", it)
log("icon search path: %s", it.get_search_path())
log("contexts: %s", it.list_contexts())
icons = []
for context in it.list_contexts():
icons += it.list_icons(context)
log("icons: %s", icons)
capabilities["theme.default.icons"] = tuple(set(icons))
if METADATA_SUPPORTED:
ms = [x.strip() for x in METADATA_SUPPORTED.split(",")]
else:
Expand Down Expand Up @@ -758,7 +765,10 @@ def make_hello(self):


def has_transparency(self):
return screen_get_default().get_rgba_visual() is not None
screen = screen_get_default()
if screen is None:
return is_Wayland()
return screen.get_rgba_visual() is not None


def get_screen_sizes(self, xscale=1, yscale=1):
Expand Down
6 changes: 4 additions & 2 deletions src/xpra/client/gtk_base/gtk_keyboard_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ def __init__(self, *args):
#(as we may be getting dozens of such events at a time)
self._keymap_changing = False
self._keymap_change_handler_id = None
self._keymap = None
display = display_get_default()
self._keymap = keymap_get_for_display(display)
if display:
self._keymap = keymap_get_for_display(display)
self.update()
if self._keymap:
self._keymap_change_handler_id = self._keymap.connect("keys-changed", self.keymap_changed)
Expand Down Expand Up @@ -67,7 +69,7 @@ def update(self):
return old_hash!=self.hash

def get_full_keymap(self):
return get_gtk_keymap()
return get_gtk_keymap()

def cleanup(self):
KeyboardHelper.cleanup(self)
Expand Down
1 change: 1 addition & 0 deletions src/xpra/gtk_common/gobject_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def import_gtk3():
gi_gtk()
from gi.repository import Gtk #@UnresolvedImport
try_import_GdkX11()
Gtk.init()
return Gtk
def import_gtk():
return _try_import(import_gtk3, import_gtk2)
Expand Down
26 changes: 16 additions & 10 deletions src/xpra/gtk_common/gtk_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
import array

from xpra.util import iround, first_time
from xpra.os_util import strtobytes, bytestostr, WIN32, OSX, PYTHON2
from xpra.os_util import (
strtobytes, bytestostr,
WIN32, OSX, PYTHON2, POSIX, is_Wayland,
)
from xpra.gtk_common.gobject_compat import (
import_gtk, import_gdk, import_glib, import_pixbufloader,
import_pango, import_cairo, import_gobject, import_pixbuf, is_gtk3,
Expand Down Expand Up @@ -195,20 +198,21 @@ def color_parse(*args):
def get_xwindow(w):
return w.get_xid()
def get_default_root_window():
return gdk.Screen.get_default().get_root_window()
screen = gdk.Screen.get_default()
if screen is None:
return None
return screen.get_root_window()
def get_root_size():
if WIN32:
if WIN32 or (POSIX and not OSX):
#FIXME: hopefully, we can remove this code once GTK3 on win32 is fixed?
#we do it the hard way because the root window geometry is invalid on win32:
#and even just querying it causes this warning:
#"GetClientRect failed: Invalid window handle."
display = gdk.Display.get_default()
n = display.get_n_screens()
w, h = 0, 0
for i in range(n):
screen = display.get_screen(i)
w += screen.get_width()
h += screen.get_height()
screen = gdk.Screen.get_default()
if screen is None:
return 1920, 1024
w = screen.get_width()
h = screen.get_height()
else:
#the easy way for platforms that work out of the box:
root = get_default_root_window()
Expand Down Expand Up @@ -913,6 +917,8 @@ def ys(v):
def swork(*workarea):
return xs(workarea[0]), ys(workarea[1]), xs(workarea[2]), ys(workarea[3])
display = display_get_default()
if not display:
return ()
n_screens = display.get_n_screens()
get_n_monitors = getattr(display, "get_n_monitors", None)
if get_n_monitors:
Expand Down
2 changes: 2 additions & 0 deletions src/xpra/gtk_common/keymap.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ def get_gtk_keymap(ignore_keys=(None, "VoidSymbol", "0xffffff")):
from xpra.gtk_common.gtk_util import keymap_get_for_display, display_get_default, import_gdk, is_gtk3
gdk = import_gdk()
display = display_get_default()
if not display:
return ()
keymap = keymap_get_for_display(display)
log("keymap_get_for_display(%s)=%s, direction=%s, bidirectional layouts: %s",
display, keymap, keymap.get_direction(), keymap.have_bidi_layouts())
Expand Down
9 changes: 8 additions & 1 deletion src/xpra/x11/gtk3/gdk_bindings.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,17 @@ cdef extern from "gdk_x11_macros.h":
int is_x11_display(void *)

def is_X11_Display(display=None):
cdef GdkDisplay *gdk_display
if display is None:
manager = Gdk.DisplayManager.get()
display = manager.get_default_display()
return bool(is_x11_display(get_raw_display_for(display)))
if display is None:
return False
try:
gdk_display = get_raw_display_for(display)
except TypeError:
return False
return bool(is_x11_display(gdk_display))

###################################
# Headers, python magic
Expand Down

0 comments on commit 2a52f27

Please sign in to comment.