<commit_before>import sys
import os
import mmap
import cairocffi as cairo
import wayland.protocol
from wayland.client import MakeDisplay
from wayland.utils import AnonymousFile
import math

import select
import time
import logging

# See https://github.com/sde1000/python-xkbcommon for the following:
from xkbcommon import xkb

log = logging.getLogger(__name__)

shutdowncode = None

# List of future events; objects must support the nexttime attribute
# and alarm() method. nexttime should be the time at which the object
# next wants to be called, or None if the object temporarily does not
# need to be scheduled.
eventlist = []

# List of file descriptors to watch with handlers.  Expected to be objects
# with a fileno() method that returns the appropriate fd number, and methods
# called doread(), dowrite(), etc.
rdlist = []

# List of functions to invoke each time around the event loop.  These
# functions may do anything, including changing timeouts and drawing
# on the display.
ticklist = []

# List of functions to invoke before calling select.  These functions
# may not change timeouts or draw on the display.  They will typically
# flush queued output.
preselectlist = []

class time_guard(object):
    def __init__(self, name, max_time):
        self._name = name
        self._max_time = max_time
    def __enter__(self):
        self._start_time = time.time()
    def __exit__(self, type, value, traceback):
        t = time.time()
        time_taken = t - self._start_time
        if time_taken > self._max_time:
            log.info("time_guard: %s took %f seconds",self._name,time_taken)

tick_time_guard = time_guard("tick",0.5)
preselect_time_guard = time_guard("preselect",0.1)
doread_time_guard = time_guard("doread",0.5)
dowrite_time_guard = time_guard("dowrite",0.5)
doexcept_time_guard = time_guard("doexcept",0.5)
alarm_time_guard = time_guard("alarm",0.5)

def eventloop():
    global shutdowncode
    while shutdowncode is None:
        for i in ticklist:
            with tick_time_guard:
                i()
        # Work out what the earliest timeout is
        timeout = None
        t = time.time()
        for i in eventlist:
            nt = i.nexttime
            i.mainloopnexttime = nt
            if nt is None:
                continue
            if timeout is None or (nt - t) < timeout:
                timeout = nt - t
        for i in preselectlist:
            with preselect_time_guard:
                i()
        try:
            (rd, wr, ex) = select.select(rdlist, [], [], timeout)
        except KeyboardInterrupt:
            (rd, wr, ex) = [], [], []
            shutdowncode = 1
        for i in rd:
            with doread_time_guard:
                i.doread()
        for i in wr:
            with dowrite_time_guard:
                i.dowrite()
        for i in ex:
            with doexcept_time_guard:
                i.doexcept()
        # Process any events whose time has come
        t = time.time()
        for i in eventlist:
            if not hasattr(i, 'mainloopnexttime'):
                continue
            if i.mainloopnexttime and t >= i.mainloopnexttime:
                with alarm_time_guard:
                    i.alarm()


class Window:
    def __init__(self, connection, width, height, title="Window",
                 class_="python-wayland-test", redraw=None, fullscreen=False):
        self.title = title
        self.orig_width = width
        self.orig_height = height
        self._w = connection
        if not self._w.shm_formats:
            raise RuntimeError("No suitable Shm formats available")
        self.is_fullscreen = fullscreen
        self.redraw_func = redraw
        self.surface = self._w.compositor.create_surface()
        self._w.surfaces[self.surface] = self
        self.shell_surface = self._w.shell.get_shell_surface(self.surface)
        if fullscreen:
            self.shell_surface.set_fullscreen(0, 0, None)
        else:
            self.shell_surface.set_toplevel()
        self.shell_surface.set_title(title)
        self.shell_surface.set_class(class_)
        self.shell_surface.dispatcher['ping'] = self._shell_surface_ping_handler
        self.shell_surface.dispatcher['configure'] = \
            self._shell_surface_configure_handler

        self.buffer = None
        if not fullscreen:
            self.resize(width, height)

    def close(self):
        if not self.surface.destroyed:
            self.surface.destroy()
            self.buffer.destroy()
            self.shm_data.close()
            del self.s, self.buffer, self.shm_data

    def resize(self, width, height):
        # Drop previous buffer and shm data if necessary
        if self.buffer:
            self.buffer.destroy()
            self.shm_data.close()

        wl_shm_format, cairo_shm_format = self._w.shm_formats[0]
        
        stride = cairo.ImageSurface.format_stride_for_width(
            cairo_shm_format, width)
        size = stride * height

        with AnonymousFile(size) as fd:
            self.shm_data = mmap.mmap(
                fd, size, prot=mmap.PROT_READ | mmap.PROT_WRITE,
                flags=mmap.MAP_SHARED)
            pool = self._w.shm.create_pool(fd, size)
            self.buffer = pool.create_buffer(
                0, width, height, stride, wl_shm_format)
            pool.destroy()
        self.s = cairo.ImageSurface(cairo_shm_format, width, height,
                                    data=self.shm_data, stride=stride)
        self.surface.attach(self.buffer, 0, 0)
        self.width = width
        self.height = height
        if self.redraw_func:
            self.redraw_func(self)
        self.surface.commit()

    def redraw(self):
        """Copy the whole window surface to the display"""
        self.add_damage()
        self.commit()

    def add_damage(self, x=0, y=0, width=None, height=None):
        if width is None:
            width = self.width
        if height is None:
            height = self.height
        self.surface.damage(x, y, width, height)

    def commit(self):
        self.surface.commit()

    def pointer_motion(self, seat, time, x, y):
        pass

    def _shell_surface_ping_handler(self, shell_surface, serial):
        shell_surface.pong(serial)

    def _shell_surface_configure_handler(
            self, shell_surface, edges, width, height):
        self.resize(width, height)

class Seat:
    def __init__(self, obj, connection, global_name):
        self.c_enum = connection.wp.interfaces['wl_seat'].enums['capability']
        self.s = obj
        self._c = connection
        self.global_name = global_name
        self.name = None
        self.capabilities = 0
        self.pointer = None
        self.keyboard = None
        self.s.dispatcher['capabilities'] = self._capabilities
        self.s.dispatcher['name'] = self._name
        self.tabsym = xkb.keysym_from_name("Tab")

    def removed(self):
        if self.pointer:
            self.pointer.release()
            self.pointer = None
        if self.keyboard:
            self.keyboard.release()
            del self.keyboard_state
            self.keyboard = None<commit_msg>Fix for closing windows<commit_after>import sys
import os
import mmap
import cairocffi as cairo
import wayland.protocol
from wayland.client import MakeDisplay
from wayland.utils import AnonymousFile
import math

import select
import time
import logging

# See https://github.com/sde1000/python-xkbcommon for the following:
from xkbcommon import xkb

log = logging.getLogger(__name__)

shutdowncode = None

# List of future events; objects must support the nexttime attribute
# and alarm() method. nexttime should be the time at which the object
# next wants to be called, or None if the object temporarily does not
# need to be scheduled.
eventlist = []

# List of file descriptors to watch with handlers.  Expected to be objects
# with a fileno() method that returns the appropriate fd number, and methods
# called doread(), dowrite(), etc.
rdlist = []

# List of functions to invoke each time around the event loop.  These
# functions may do anything, including changing timeouts and drawing
# on the display.
ticklist = []

# List of functions to invoke before calling select.  These functions
# may not change timeouts or draw on the display.  They will typically
# flush queued output.
preselectlist = []

class time_guard(object):
    def __init__(self, name, max_time):
        self._name = name
        self._max_time = max_time
    def __enter__(self):
        self._start_time = time.time()
    def __exit__(self, type, value, traceback):
        t = time.time()
        time_taken = t - self._start_time
        if time_taken > self._max_time:
            log.info("time_guard: %s took %f seconds",self._name,time_taken)

tick_time_guard = time_guard("tick",0.5)
preselect_time_guard = time_guard("preselect",0.1)
doread_time_guard = time_guard("doread",0.5)
dowrite_time_guard = time_guard("dowrite",0.5)
doexcept_time_guard = time_guard("doexcept",0.5)
alarm_time_guard = time_guard("alarm",0.5)

def eventloop():
    global shutdowncode
    while shutdowncode is None:
        for i in ticklist:
            with tick_time_guard:
                i()
        # Work out what the earliest timeout is
        timeout = None
        t = time.time()
        for i in eventlist:
            nt = i.nexttime
            i.mainloopnexttime = nt
            if nt is None:
                continue
            if timeout is None or (nt - t) < timeout:
                timeout = nt - t
        for i in preselectlist:
            with preselect_time_guard:
                i()
        try:
            (rd, wr, ex) = select.select(rdlist, [], [], timeout)
        except KeyboardInterrupt:
            (rd, wr, ex) = [], [], []
            shutdowncode = 1
        for i in rd:
            with doread_time_guard:
                i.doread()
        for i in wr:
            with dowrite_time_guard:
                i.dowrite()
        for i in ex:
            with doexcept_time_guard:
                i.doexcept()
        # Process any events whose time has come
        t = time.time()
        for i in eventlist:
            if not hasattr(i, 'mainloopnexttime'):
                continue
            if i.mainloopnexttime and t >= i.mainloopnexttime:
                with alarm_time_guard:
                    i.alarm()


class Window:
    def __init__(self, connection, width, height, title="Window",
                 class_="python-wayland-test", redraw=None, fullscreen=False):
        self.title = title
        self.orig_width = width
        self.orig_height = height
        self._w = connection
        if not self._w.shm_formats:
            raise RuntimeError("No suitable Shm formats available")
        self.is_fullscreen = fullscreen
        self.redraw_func = redraw
        self.surface = self._w.compositor.create_surface()
        self._w.surfaces[self.surface] = self
        self.shell_surface = self._w.shell.get_shell_surface(self.surface)
        if fullscreen:
            self.shell_surface.set_fullscreen(0, 0, None)
        else:
            self.shell_surface.set_toplevel()
        self.shell_surface.set_title(title)
        self.shell_surface.set_class(class_)
        self.shell_surface.dispatcher['ping'] = self._shell_surface_ping_handler
        self.shell_surface.dispatcher['configure'] = \
            self._shell_surface_configure_handler

        self.buffer = None
        if not fullscreen:
            self.resize(width, height)

    def close(self):
        if not self.surface.destroyed:
            self.surface.destroy()
            self.buffer.destroy()
            self.buffer = None
            self.shm_data.close()
            del self.s, self.shm_data

    def resize(self, width, height):
        # Drop previous buffer and shm data if necessary
        if self.buffer:
            self.buffer.destroy()
            self.shm_data.close()

        wl_shm_format, cairo_shm_format = self._w.shm_formats[0]
        
        stride = cairo.ImageSurface.format_stride_for_width(
            cairo_shm_format, width)
        size = stride * height

        with AnonymousFile(size) as fd:
            self.shm_data = mmap.mmap(
                fd, size, prot=mmap.PROT_READ | mmap.PROT_WRITE,
                flags=mmap.MAP_SHARED)
            pool = self._w.shm.create_pool(fd, size)
            self.buffer = pool.create_buffer(
                0, width, height, stride, wl_shm_format)
            pool.destroy()
        self.s = cairo.ImageSurface(cairo_shm_format, width, height,
                                    data=self.shm_data, stride=stride)
        self.surface.attach(self.buffer, 0, 0)
        self.width = width
        self.height = height
        if self.redraw_func:
            self.redraw_func(self)
        self.surface.commit()

    def redraw(self):
        """Copy the whole window surface to the display"""
        self.add_damage()
        self.commit()

    def add_damage(self, x=0, y=0, width=None, height=None):
        if width is None:
            width = self.width
        if height is None:
            height = self.height
        self.surface.damage(x, y, width, height)

    def commit(self):
        self.surface.commit()

    def pointer_motion(self, seat, time, x, y):
        pass

    def _shell_surface_ping_handler(self, shell_surface, serial):
        shell_surface.pong(serial)

    def _shell_surface_configure_handler(
            self, shell_surface, edges, width, height):
        if not self.surface.destroyed:
            self.resize(width, height)

class Seat:
    def __init__(self, obj, connection, global_name):
        self.c_enum = connection.wp.interfaces['wl_seat'].enums['capability']
        self.s = obj
        self._c = connection
        self.global_name = global_name
        self.name = None
        self.capabilities = 0
        self.pointer = None
        self.keyboard = None
        self.s.dispatcher['capabilities'] = self._capabilities
        self.s.dispatcher['name'] = self._name
        self.tabsym = xkb.keysym_from_name("Tab")

    def removed(self):
        if self.pointer:
            self.pointer.release()
            self.pointer = None
        if self.keyboard:
            self.keyboard.release()
            del self.keyboard_state
            self.keyboard = None
{'fraction_non_alphanumeric': 0.08800780433419274, 'fraction_numerical': 0.0036234408752003344, 'mean_word_length': 2.1480587848212327, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5534626', 'n_tokens_mistral': 4244, 'n_tokens_neox': 4133, 'n_words': 1122}