<commit_before>#include "pointer.h"

#include "compositor/view.h"
#include "compositor/surface.h"

#include <stdlib.h>
#include <assert.h>

#include <wayland-server.h>

void
wlc_pointer_focus(struct wlc_pointer *pointer, uint32_t serial, struct wlc_view *view, int32_t x,  int32_t y)
{
   assert(pointer);

   if (pointer->focus == view)
      return;

   if (!view) {
      if (pointer->focus) {
         pointer->focus = NULL;
         pointer->grabbing = false;
         pointer->action = WLC_GRAB_ACTION_NONE;
         pointer->action_edges = 0;
      }
      return;
   }

   if (pointer->focus && pointer->focus->input[WLC_POINTER])
      wl_pointer_send_leave(pointer->focus->input[WLC_POINTER], serial, pointer->focus->surface->resource);

   if (view->input[WLC_POINTER]) {
      wl_pointer_send_enter(view->input[WLC_POINTER], serial, view->surface->resource, wl_fixed_from_int(x), wl_fixed_from_int(y));
      pointer->focus = view;
   } else {
      pointer->focus = NULL;
   }

   pointer->grabbing = false;
   pointer->action = WLC_GRAB_ACTION_NONE;
   pointer->action_edges = 0;
}

void
wlc_pointer_button(struct wlc_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, enum wl_pointer_button_state state)
{
   assert(pointer);

   if (!pointer->focus)
      return;

   if (state == WL_POINTER_BUTTON_STATE_PRESSED && !pointer->grabbing) {
      pointer->grabbing = true;
      pointer->gx = pointer->x;
      pointer->gy = pointer->y;
   } else if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
      pointer->grabbing = false;
      pointer->action = WLC_GRAB_ACTION_NONE;
      pointer->action_edges = 0;
   }

   wl_pointer_send_button(pointer->focus->input[WLC_POINTER], serial, time, button, state);
}

void
wlc_pointer_motion(struct wlc_pointer *pointer, uint32_t serial, uint32_t time, int32_t x, int32_t y)
{
   assert(pointer);

   pointer->x = wl_fixed_from_int(x);
   pointer->y = wl_fixed_from_int(y);

   struct wlc_view *focused = NULL;
   if (pointer->focus && pointer->grabbing) {
      focused = pointer->focus;
   } else {
      struct wlc_view *view;
      wl_list_for_each(view, pointer->views, link) {
         if (x >= view->x && x <= view->x + view->surface->width &&
             y >= view->y && y <= view->y + view->surface->height) {
            focused = view;
            break;
         }
      }
   }

   if (!focused) {
      wlc_pointer_focus(pointer, 0, NULL, 0, 0);<commit_msg>Reverse search for pointer focus so that it works correctly.<commit_after>#include "pointer.h"

#include "compositor/view.h"
#include "compositor/surface.h"

#include <stdlib.h>
#include <assert.h>

#include <wayland-server.h>

void
wlc_pointer_focus(struct wlc_pointer *pointer, uint32_t serial, struct wlc_view *view, int32_t x,  int32_t y)
{
   assert(pointer);

   if (pointer->focus == view)
      return;

   if (!view) {
      if (pointer->focus) {
         pointer->focus = NULL;
         pointer->grabbing = false;
         pointer->action = WLC_GRAB_ACTION_NONE;
         pointer->action_edges = 0;
      }
      return;
   }

   if (pointer->focus && pointer->focus->input[WLC_POINTER])
      wl_pointer_send_leave(pointer->focus->input[WLC_POINTER], serial, pointer->focus->surface->resource);

   if (view->input[WLC_POINTER]) {
      wl_pointer_send_enter(view->input[WLC_POINTER], serial, view->surface->resource, wl_fixed_from_int(x), wl_fixed_from_int(y));
      pointer->focus = view;
   } else {
      pointer->focus = NULL;
   }

   pointer->grabbing = false;
   pointer->action = WLC_GRAB_ACTION_NONE;
   pointer->action_edges = 0;
}

void
wlc_pointer_button(struct wlc_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, enum wl_pointer_button_state state)
{
   assert(pointer);

   if (!pointer->focus)
      return;

   if (state == WL_POINTER_BUTTON_STATE_PRESSED && !pointer->grabbing) {
      pointer->grabbing = true;
      pointer->gx = pointer->x;
      pointer->gy = pointer->y;
   } else if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
      pointer->grabbing = false;
      pointer->action = WLC_GRAB_ACTION_NONE;
      pointer->action_edges = 0;
   }

   wl_pointer_send_button(pointer->focus->input[WLC_POINTER], serial, time, button, state);
}

void
wlc_pointer_motion(struct wlc_pointer *pointer, uint32_t serial, uint32_t time, int32_t x, int32_t y)
{
   assert(pointer);

   pointer->x = wl_fixed_from_int(x);
   pointer->y = wl_fixed_from_int(y);

   struct wlc_view *focused = NULL;
   if (pointer->focus && pointer->grabbing) {
      focused = pointer->focus;
   } else {
      struct wlc_view *view;
      wl_list_for_each_reverse(view, pointer->views, link) {
         if (x >= view->x && x <= view->x + view->surface->width &&
             y >= view->y && y <= view->y + view->surface->height) {
            focused = view;
            break;
         }
      }
   }

   if (!focused) {
      wlc_pointer_focus(pointer, 0, NULL, 0, 0);
{'fraction_non_alphanumeric': 0.13550739315373708, 'fraction_numerical': 0.010532712173384647, 'mean_word_length': 3.181202370872142, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 111, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1503635', 'n_tokens_mistral': 1782, 'n_tokens_neox': 1698, 'n_words': 334}