#! /usr/bin/python3
# -*- coding: UTF-8 -*-

# Copyright © 2007 Martin Böhme <martin.bohm@kubuntu.org>
# Copyright © 2009 Chris Jones <tortoise@tortuga>
# Copyright © 2012 marmuta <marmvta@gmail.com>
#
# This file is part of Onboard.
#
# Onboard is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Onboard is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from __future__ import division, print_function, unicode_literals

__copyright__ = "Copyright © 2009 Chris Jones"
__author__    = "Chris Jones <chrisejones@gmail.com>"

import sys
import os


def is_wayland_environment():
    backends = [
        item.strip().lower()
        for item in os.getenv("GDK_BACKEND", "").split(",")
        if item.strip()
    ]
    if "wayland" in backends:
        return True

    session_type = os.getenv("XDG_SESSION_TYPE", "").lower()
    if session_type == "wayland":
        return True

    return bool(os.getenv("WAYLAND_DISPLAY"))


# ---------------------------------------------------------------------------
# Wayland backend selection, before any ``gi.repository`` import.
# ---------------------------------------------------------------------------
# Onboard's Wayland support needs either:
#   (a) the KWin window-rule mechanism (KDE Plasma), or
#   (b) the wlr-layer-shell protocol (Pop_OS, sway, Hyprland, ...),
# in order to (i) stay above other windows, (ii) refuse keyboard
# focus, and (iii) reserve screen space for docking.
#
# Mutter (GNOME) implements neither, so we either use a shell extension
# or set GDK_BACKEND=x11 and route through XWayland.
def _auto_select_backend():
    if os.environ.get("GDK_BACKEND"):           # explicit user override wins
        return
    if not is_wayland_environment():
        return
    desktop = os.environ.get("XDG_CURRENT_DESKTOP", "")
    if "KDE" in desktop or "Plasma" in desktop:
        return                                   # KWin-rule path handles it
    import subprocess
    # GNOME: if the bundled Onboard Shell extension is already enabled
    # *and* gnome-shell is running the current build, stay on Wayland.
    # Otherwise, go through the installation.
    if "GNOME" in desktop:
        from Onboard.WaylandGnomeExtensionUtils import (
            is_gnome_extension_installed_and_current,
            install_gnome_extension)
        if is_gnome_extension_installed_and_current():
            return                               # native Wayland on GNOME
        # Extension not enabled, not installed, or running shell has
        # stale code. Try to install + enable + verify.
        # WaylandGnomeExtensionUtils is stdlib-only by design, so calling
        # install_gnome_extension() here can't pollute the parent's gi
        # namespace before we've finished picking the backend.
        # install_gnome_extension() returns True iff the extension ends up enabled;
        # it also respects user opt-out (already-installed-but-disabled
        # is treated as "stay on XWayland").
        if install_gnome_extension():
            return                               # native Wayland on GNOME
    # Probe layer-shell support out-of-process so a failed probe (missing
    # typelib, broken introspection) can't pollute the parent's GI namespace.
    code = (
        "import gi; gi.require_version('GtkLayerShell','0.1');"
        "from gi.repository import GtkLayerShell;"
        "import sys; sys.exit(0 if GtkLayerShell.is_supported() else 1)"
    )
    try:
        r = subprocess.run([sys.executable, "-c", code],
                           timeout=3, capture_output=True)
        layer_shell_works = (r.returncode == 0)
    except (subprocess.SubprocessError, FileNotFoundError, OSError):
        layer_shell_works = False
    if not layer_shell_works:
        os.environ["GDK_BACKEND"] = "x11"
        os.environ.setdefault("ONBOARD_AUTO_XWAYLAND", "1")


_auto_select_backend()


# Replace the default exception handler with one which handles chained
# exceptions.
from Onboard.Exceptions import chain_handler
sys.excepthook = chain_handler

from Onboard.OnboardGtk import OnboardGtk as Onboard
ob = Onboard()
