#!/usr/bin/env python

import sys
import pyatspi
import signal

# to move the mouse at posisition
from Xlib import X, display
d = display.Display()
s = d.screen()
root = s.root

foundOrca = False
import psutil
for p in psutil.process_iter():
    if 'orca' in p.name() or 'orca' in ' '.join(p.cmdline()):
        foundOrca = True
if not foundOrca:
    print("orca not found on your system, please start orca to ensure a11y layer responds.")
    sys.exit(1)

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject

variable = raw_input('This script is a demo for bug https://bugzilla.gnome.org/show_bug.cgi?id=784509\n\nThis script will move the MOUSE cursor (not caret) to the position of typed letters.\nin the test entry, mouse cursor should be synchronized with letters.\nIn buggy mate-panel alt-F2 entry, mouse cursor will be de-synced with the letters. This shows that wrong coordinates are given to the A11Y bus')

class EntryWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Bug 784509 demo")
        self.set_size_request(200, 100)

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(vbox)

        self.entry = Gtk.Entry()
        self.entry.set_text("try me, then look at the results")
        vbox.pack_start(self.entry, True, True, 0)

# I left all these so one can play around to see if they can see an impact.

        hbox = Gtk.Box(spacing=6)
        vbox.pack_start(hbox, True, True, 0)

        self.check_editable = Gtk.CheckButton("Editable")
        self.check_editable.connect("toggled", self.on_editable_toggled)
        self.check_editable.set_active(True)
        hbox.pack_start(self.check_editable, True, True, 0)

        self.check_visible = Gtk.CheckButton("Visible")
        self.check_visible.connect("toggled", self.on_visible_toggled)
        self.check_visible.set_active(True)
        hbox.pack_start(self.check_visible, True, True, 0)

        self.icon = Gtk.CheckButton("Icon")
        self.icon.connect("toggled", self.on_icon_toggled)
        self.icon.set_active(False)
        hbox.pack_start(self.icon, True, True, 0)

    def on_editable_toggled(self, button):
        value = button.get_active()
        self.entry.set_editable(value)

    def on_visible_toggled(self, button):
        value = button.get_active()
        self.entry.set_visibility(value)

    def on_icon_toggled(self, button):
        if button.get_active():
            icon_name = "system-search-symbolic"
        else:
            icon_name = None
        self.entry.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,
                icon_name)


def print_changed(event):
    if "erminal" in event.host_application.name:
        return
    #if "bug_784509_demo.py" not in event.host_application.name:
    #	return

    print("{0}, {1}, {2}, {3}".format(event.host_application.name,
    event.source.getRoleName(),
    event.type,
    event.detail1)) # offset

    #print(type(event.source))
    rect = event.source.get_character_extents(event.detail1, 0)

    #print(rect)
    print("position: {0},{1} ({2}x{3}), ".format(rect.x, rect.y, rect.width, rect.height))
    #print("warping pointer to {0},{1}".format(rect.x + int(rect.width/2), rect.y + int(rect.height/2)))
    root.warp_pointer(rect.x + int(rect.width/2), rect.y + int(rect.height/2))
    d.sync()

def signal_handler(signal, frame):
    sys.exit(0)


if __name__ == "__main__":
    pyatspi.Registry.registerEventListener(print_changed,
            'object:text-caret-moved',
            'object:text-changed:inserted',
            'object:text-changed:insert',  # replaces inserted in debian stretch?
            'object:text-changed:removed',
            'object:text-selection-changed',
            'object:state-changed:selected',
            )

    win = EntryWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()

    signal.signal(signal.SIGINT, signal_handler)
    pyatspi.Registry.start()
