<commit_before>#include "window.h"
#include "container.h"
#include "node.h"
#include "display.h"
#include "space.h"
#include "tree.h"
#include "application.h"
#include "border.h"
#include "helpers.h"
#include "rules.h"
#include "serializer.h"

#include "axlib/axlib.h"

#include <cmath>

extern std::map<CFStringRef, space_info> WindowTree;

extern ax_state AXState;
extern ax_display *FocusedDisplay;
extern ax_application *FocusedApplication;

extern kwm_screen KWMScreen;
extern kwm_focus KWMFocus;
extern kwm_toggles KWMToggles;
extern kwm_mode KWMMode;
extern kwm_tiling KWMTiling;
extern kwm_cache KWMCache;
extern kwm_path KWMPath;
extern kwm_thread KWMThread;
extern kwm_border MarkedBorder;
extern kwm_border FocusedBorder;

EVENT_CALLBACK(Callback_AXEvent_DisplayAdded)
{
    DEBUG("AXEvent_DisplayAdded");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayRemoved)
{
    DEBUG("AXEvent_DisplayRemoved");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayResized)
{
    DEBUG("AXEvent_DisplayResized");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayMoved)
{
    DEBUG("AXEvent_DisplayMoved");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayChanged)
{
    FocusedDisplay = AXLibMainDisplay();
    printf("%d: AXEvent_DisplayChanged\n", FocusedDisplay->ArrangementID);
}

/* TODO(koekeishiya): If we trigger a space changed event through cmd+tab, we receive the 'didApplicationActivate'
                      notification before the 'didActiveSpaceChange' notification. If a space has not been visited
                      before, this will cause us to end up on that space with a unsynchronized focused application state. */
EVENT_CALLBACK(Callback_AXEvent_SpaceChanged)
{
    DEBUG("AXEvent_SpaceChanged");
    AXLibRunningApplications();
    ax_display *Display  = AXLibMainDisplay();
    if(Display)
    {
        FocusedDisplay = Display;
        FocusedDisplay->Space = AXLibGetActiveSpace(FocusedDisplay);
        printf("Display: CGDirectDisplayID %d, Arrangement %d\n", FocusedDisplay->ID, FocusedDisplay->ArrangementID);
        printf("Space: CGSSpaceID %d\n", FocusedDisplay->Space->ID);

        CreateWindowNodeTree(FocusedDisplay);
        RebalanceNodeTree(FocusedDisplay);
    }
    else
    {
        printf("What the fuck.. Display was null (?)");
    }
}

/* TODO(koekeishiya): Is this interesting (?)
EVENT_CALLBACK(Callback_AXEvent_SpaceCreated)
{
    ax_space *Space = (ax_space *) Event->Context;
}
*/

EVENT_CALLBACK(Callback_AXEvent_ApplicationLaunched)
{
    ax_application *Application = (ax_application *) Event->Context;
    DEBUG("AXEvent_ApplicationLaunched: " << Application->Name);

    /* NOTE(koekeishiya): Some applications fail to properly create notifications upon launch.
                          Force applications to register failed notifications. */
    AXLibAddApplicationObserverNotificationFallback(Application);

    if(Application->Focus)
    {
        ApplyWindowRules(Application->Focus);
        ax_display *Display = AXLibWindowDisplay(Application->Focus);
        if(Display)
        {
            if((!AXLibHasFlags(Application->Focus, AXWindow_Minimized)) &&
               (AXLibIsWindowStandard(Application->Focus) || AXLibIsWindowCustom(Application->Focus)) &&
               (!AXLibHasFlags(Application->Focus, AXWindow_Floating)))
            {
                AddWindowToNodeTree(Display, Application->Focus->ID);
            }
        }
    }
}

EVENT_CALLBACK(Callback_AXEvent_ApplicationTerminated)
{
    DEBUG("AXEvent_ApplicationTerminated");

    /* TODO(koekeishiya): We probably want to flag every display for an update, as the application
                          in question could have had windows on several displays and spaces. */
    ax_display *Display = AXLibMainDisplay();
    if(Display)
        RebalanceNodeTree(Display);

    ClearBorder(&FocusedBorder);
}

EVENT_CALLBACK(Callback_AXEvent_ApplicationActivated)
{
    ax_application *Application = (ax_application *) Event->Context;
    ax_application *OldFocusedApplication = FocusedApplication;

    FocusedApplication = Application;
    FocusedApplication->Focus = AXLibGetFocusedWindow(FocusedApplication);

    /* NOTE(koekeishiya): When an application that is already running, but has no open windows, is activated,
                          or a window is deminimized, we receive 'didApplicationActivate' notification first.
                          We have to preserve our insertion point and flag this application for activation at a later point in time. */

    if((!FocusedApplication->Focus) ||
       (AXLibHasFlags(FocusedApplication->Focus, AXWindow_Minimized)))
    {
        FocusedApplication = OldFocusedApplication;
        AXLibAddFlags(Application, AXApplication_Activate);
    }
    else
    {
        DEBUG("AXEvent_ApplicationActivated: " << Application->Name);
        UpdateBorder("focused");
    }
}

EVENT_CALLBACK(Callback_AXEvent_WindowCreated)
{
    ax_window *Window = (ax_window *) Event->Context;
    if(Window && AXLibFindApplicationWindow(Window->Application, Window->ID))
    {
        DEBUG("AXEvent_WindowCreated: " << Window->Application->Name << " - " << Window->Name);
        ApplyWindowRules(Window);
        ax_display *Display = AXLibWindowDisplay(Window);
        if(Display)
        {
            if((!AXLibHasFlags(Window, AXWindow_Minimized)) &&
               (AXLibIsWindowStandard(Window) || AXLibIsWindowCustom(Window)) &&
               (!AXLibHasFlags(Window, AXWindow_Floating)))
            {
                AddWindowToNodeTree(Display, Window->ID);
            }
        }
    }
}

EVENT_CALLBACK(Callback_AXEvent_WindowDestroyed)
{
    ax_window *Window = (ax_window *) Event->Context;
    DEBUG("AXEvent_WindowDestroyed: " << Window->Application->Name << " - " << Window->Name);
    ax_display *Display = AXLibWindowDisplay(Window);
    if(Display)
        RemoveWindowFromNodeTree(Display, Window->ID);

    UpdateBorder("focused");
    AXLibDestroyWindow(Window);
}

EVENT_CALLBACK(Callback_AXEvent_WindowMinimized)
{
    ax_window *Window = (ax_window *) Event->Context;
    DEBUG("AXEvent_WindowMinimized: " << Window->Application->Name << " - " << Window->Name);
    AXLibAddFlags(Window, AXWindow_Minimized);

    ax_display *Display = AXLibWindowDisplay(Window);
    if(Display)
        RemoveWindowFromNodeTree(Display, Window->ID);

    ClearBorder(&FocusedBorder);
}

EVENT_CALLBACK(Callback_AXEvent_WindowDeminimized)
{
    ax_window *Window = (ax_window *) Event->Context;
    DEBUG("AXEvent_WindowDeminimized: " << Window->Application->Name << " - " << Window->Name);

    ax_display *Display = AXLibWindowDisplay(Window);
    if(Display)
    {
        if((AXLibIsWindowStandard(Window) || AXLibIsWindowCustom(Window)) &&<commit_msg>add note regarding unordered deminimized and space changed events<commit_after>#include "window.h"
#include "container.h"
#include "node.h"
#include "display.h"
#include "space.h"
#include "tree.h"
#include "application.h"
#include "border.h"
#include "helpers.h"
#include "rules.h"
#include "serializer.h"

#include "axlib/axlib.h"

#include <cmath>

extern std::map<CFStringRef, space_info> WindowTree;

extern ax_state AXState;
extern ax_display *FocusedDisplay;
extern ax_application *FocusedApplication;

extern kwm_screen KWMScreen;
extern kwm_focus KWMFocus;
extern kwm_toggles KWMToggles;
extern kwm_mode KWMMode;
extern kwm_tiling KWMTiling;
extern kwm_cache KWMCache;
extern kwm_path KWMPath;
extern kwm_thread KWMThread;
extern kwm_border MarkedBorder;
extern kwm_border FocusedBorder;

EVENT_CALLBACK(Callback_AXEvent_DisplayAdded)
{
    DEBUG("AXEvent_DisplayAdded");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayRemoved)
{
    DEBUG("AXEvent_DisplayRemoved");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayResized)
{
    DEBUG("AXEvent_DisplayResized");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayMoved)
{
    DEBUG("AXEvent_DisplayMoved");
}

EVENT_CALLBACK(Callback_AXEvent_DisplayChanged)
{
    FocusedDisplay = AXLibMainDisplay();
    printf("%d: AXEvent_DisplayChanged\n", FocusedDisplay->ArrangementID);
}

/* TODO(koekeishiya): If we trigger a space changed event through cmd+tab, we receive the 'didApplicationActivate'
                      notification before the 'didActiveSpaceChange' notification. If a space has not been visited
                      before, this will cause us to end up on that space with a unsynchronized focused application state. */
EVENT_CALLBACK(Callback_AXEvent_SpaceChanged)
{
    DEBUG("AXEvent_SpaceChanged");
    AXLibRunningApplications();
    ax_display *Display  = AXLibMainDisplay();
    if(Display)
    {
        FocusedDisplay = Display;
        FocusedDisplay->Space = AXLibGetActiveSpace(FocusedDisplay);
        printf("Display: CGDirectDisplayID %d, Arrangement %d\n", FocusedDisplay->ID, FocusedDisplay->ArrangementID);
        printf("Space: CGSSpaceID %d\n", FocusedDisplay->Space->ID);

        CreateWindowNodeTree(FocusedDisplay);
        RebalanceNodeTree(FocusedDisplay);
    }
    else
    {
        printf("What the fuck.. Display was null (?)");
    }
}

/* TODO(koekeishiya): Is this interesting (?)
EVENT_CALLBACK(Callback_AXEvent_SpaceCreated)
{
    ax_space *Space = (ax_space *) Event->Context;
}
*/

EVENT_CALLBACK(Callback_AXEvent_ApplicationLaunched)
{
    ax_application *Application = (ax_application *) Event->Context;
    DEBUG("AXEvent_ApplicationLaunched: " << Application->Name);

    /* NOTE(koekeishiya): Some applications fail to properly create notifications upon launch.
                          Force applications to register failed notifications. */
    AXLibAddApplicationObserverNotificationFallback(Application);

    if(Application->Focus)
    {
        ApplyWindowRules(Application->Focus);
        ax_display *Display = AXLibWindowDisplay(Application->Focus);
        if(Display)
        {
            if((!AXLibHasFlags(Application->Focus, AXWindow_Minimized)) &&
               (AXLibIsWindowStandard(Application->Focus) || AXLibIsWindowCustom(Application->Focus)) &&
               (!AXLibHasFlags(Application->Focus, AXWindow_Floating)))
            {
                AddWindowToNodeTree(Display, Application->Focus->ID);
            }
        }
    }
}

EVENT_CALLBACK(Callback_AXEvent_ApplicationTerminated)
{
    DEBUG("AXEvent_ApplicationTerminated");

    /* TODO(koekeishiya): We probably want to flag every display for an update, as the application
                          in question could have had windows on several displays and spaces. */
    ax_display *Display = AXLibMainDisplay();
    if(Display)
        RebalanceNodeTree(Display);

    ClearBorder(&FocusedBorder);
}

EVENT_CALLBACK(Callback_AXEvent_ApplicationActivated)
{
    ax_application *Application = (ax_application *) Event->Context;
    ax_application *OldFocusedApplication = FocusedApplication;

    FocusedApplication = Application;
    FocusedApplication->Focus = AXLibGetFocusedWindow(FocusedApplication);

    /* NOTE(koekeishiya): When an application that is already running, but has no open windows, is activated,
                          or a window is deminimized, we receive 'didApplicationActivate' notification first.
                          We have to preserve our insertion point and flag this application for activation at a later point in time. */

    if((!FocusedApplication->Focus) ||
       (AXLibHasFlags(FocusedApplication->Focus, AXWindow_Minimized)))
    {
        FocusedApplication = OldFocusedApplication;
        AXLibAddFlags(Application, AXApplication_Activate);
    }
    else
    {
        DEBUG("AXEvent_ApplicationActivated: " << Application->Name);
        UpdateBorder("focused");
    }
}

EVENT_CALLBACK(Callback_AXEvent_WindowCreated)
{
    ax_window *Window = (ax_window *) Event->Context;
    if(Window && AXLibFindApplicationWindow(Window->Application, Window->ID))
    {
        DEBUG("AXEvent_WindowCreated: " << Window->Application->Name << " - " << Window->Name);
        ApplyWindowRules(Window);
        ax_display *Display = AXLibWindowDisplay(Window);
        if(Display)
        {
            if((!AXLibHasFlags(Window, AXWindow_Minimized)) &&
               (AXLibIsWindowStandard(Window) || AXLibIsWindowCustom(Window)) &&
               (!AXLibHasFlags(Window, AXWindow_Floating)))
            {
                AddWindowToNodeTree(Display, Window->ID);
            }
        }
    }
}

EVENT_CALLBACK(Callback_AXEvent_WindowDestroyed)
{
    ax_window *Window = (ax_window *) Event->Context;
    DEBUG("AXEvent_WindowDestroyed: " << Window->Application->Name << " - " << Window->Name);
    ax_display *Display = AXLibWindowDisplay(Window);
    if(Display)
        RemoveWindowFromNodeTree(Display, Window->ID);

    UpdateBorder("focused");
    AXLibDestroyWindow(Window);
}

EVENT_CALLBACK(Callback_AXEvent_WindowMinimized)
{
    ax_window *Window = (ax_window *) Event->Context;
    DEBUG("AXEvent_WindowMinimized: " << Window->Application->Name << " - " << Window->Name);
    AXLibAddFlags(Window, AXWindow_Minimized);

    ax_display *Display = AXLibWindowDisplay(Window);
    if(Display)
        RemoveWindowFromNodeTree(Display, Window->ID);

    ClearBorder(&FocusedBorder);
}

/* TODO(koekeishiya): kAXWindowDeminiaturized is sent before didActiveSpaceChange, when a deminimized
                      window pulls you to the space of that window.

                      This can probably be solved by checking if the active space of the display and
                      the space of the window is equal. If they are not, we should ignore this event
                      and schedule a new one to happen after the next space changed event. */
EVENT_CALLBACK(Callback_AXEvent_WindowDeminimized)
{
    ax_window *Window = (ax_window *) Event->Context;
    DEBUG("AXEvent_WindowDeminimized: " << Window->Application->Name << " - " << Window->Name);

    ax_display *Display = AXLibWindowDisplay(Window);
    if(Display)
    {
        if((AXLibIsWindowStandard(Window) || AXLibIsWindowCustom(Window)) &&
{'fraction_non_alphanumeric': 0.10205396121090675, 'fraction_numerical': 0.0, 'mean_word_length': 3.754678462061926, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 95, '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': '711612', 'n_tokens_mistral': 4097, 'n_tokens_neox': 3961, 'n_words': 820}