Skip to content

Commit

Permalink
Sync supports for multi-platform.
Browse files Browse the repository at this point in the history
  • Loading branch information
LitnhJacuzzi committed Oct 22, 2024
1 parent 75f164f commit c3b3f12
Show file tree
Hide file tree
Showing 34 changed files with 239 additions and 63 deletions.
11 changes: 6 additions & 5 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ plugins {
}

dependencies {
implementation 'net.java.dev.jna:jna:5.12.1'
implementation 'net.java.dev.jna:jna-platform:5.12.1'
implementation 'org.apache.logging.log4j:log4j-api:2.19.0'
implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
implementation 'org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0'
compileOnly 'net.java.dev.jna:jna:5.12.1'
compileOnly 'net.java.dev.jna:jna-platform:5.12.1'
compileOnly 'org.apache.logging.log4j:log4j-api:2.19.0'
compileOnly 'org.apache.logging.log4j:log4j-core:2.19.0'
compileOnly 'org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0'
compileOnly 'ca.weblite:java-objc-bridge:1.1'
}

java {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.common;

public abstract class AxiomGuiAccessor {
public static AxiomGuiAccessor instance;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.common;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.common;

import java.util.function.Predicate;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.common;

public interface FocusableWidgetAccessor
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.common;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
Expand Down Expand Up @@ -37,7 +37,7 @@ private static void syncState() {
state = (focusedInputWidget != null && focusedInputWidget.isWidgetEditable())
|| isWhiteListScreenShowing;
}
IMManager.makeState(state);
IMManager.setState(state);
updateChatState();
}

Expand All @@ -56,7 +56,7 @@ private static void updateChatState() {
(focusedInputWidget.getText().trim().startsWith("/") ? ChatState.COMMAND : ChatState.CHAT);
if(currentChatState != ChatState.NONE && chatState != currentChatState) {
//Executing at the same tick as imstate change will nullify this operation, thus move to next tick.
deferredOp = () -> IMManager.makeImmOnState(currentChatState == ChatState.COMMAND);
deferredOp = () -> IMManager.setImmOnState(currentChatState == ChatState.COMMAND);
}
chatState = currentChatState;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.github.reserveword.imblocker.common;

import com.sun.jna.Platform;

public final class IMManager {
private static final PlatformIMManager INSTANCE;

public sealed interface PlatformIMManager permits IMManagerWindows, IMManagerMac, IMManagerStub {

void setState(boolean on);

void setImmOnState(boolean isEN);

void syncState();

boolean getState();
}

private IMManager() {}

public static void setState(boolean on) {
INSTANCE.setState(on);
}

public static void setImmOnState(boolean isEN) {
INSTANCE.setImmOnState(isEN);
}

public static boolean getState() {
return INSTANCE.getState();
}

static {
if(Platform.isWindows()) {
INSTANCE = new IMManagerWindows();
}else if(Platform.isMac()) {
INSTANCE = new IMManagerMac();
}else {
Common.LOGGER.warn("Unsupported platform, using stub");
INSTANCE = new IMManagerStub();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package io.github.reserveword.imblocker.common;

import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;

import ca.weblite.objc.Runtime;
import ca.weblite.objc.RuntimeUtils;

final class IMManagerMac implements IMManager.PlatformIMManager {
private static boolean state = false;
static private final Pointer viewClass = Runtime.INSTANCE.objc_getClass("GLFWContentView");
static private Pointer view = null;
static private final InterpretKeyEventsCallback Imp;
static private final InterpretKeyEventsCallback NewImp;


static {
// see https://github.com/glfw/glfw/blob/b4c3ef9d0fdf46845f3e81e5d989dab06e71e6c1/src/cocoa_window.m#L571
// Replacing the method dynamically to determine whether to send text based on state
// see reference for objc_runtime's dynamic manipulation at https://developer.apple.com/documentation/objectivec/objective-c_runtime
var selector = RuntimeUtils.sel("interpretKeyEvents:");
var method = Runtime.INSTANCE.class_getInstanceMethod(viewClass, selector);
Imp = ObjC.INSTANCE.method_getImplementation(method);
NewImp = (self, sel, eventArray) -> {
if (view == null) view = self;
if (!state) {
var textInputContext = RuntimeUtils.cls("NSTextInputContext");
var current = RuntimeUtils.msgPointer(textInputContext, "currentInputContext");
RuntimeUtils.msg(current, "discardMarkedText");
return;
}
Imp.invoke(self, sel, eventArray);
};
ObjC.INSTANCE.class_replaceMethod(viewClass, selector, NewImp, "v@:@");
}

/**
* @see <a href="https://developer.apple.com/documentation/objectivec/objective-c_runtime">Apple Developer Documentation for objc_runtime:</a>
*/
private interface ObjC extends Library {
ObjC INSTANCE = Native.load("objc.A", ObjC.class);

void class_replaceMethod(Pointer cls, Pointer selector, InterpretKeyEventsCallback imp, String types);

InterpretKeyEventsCallback method_getImplementation(Pointer selector);
}

/**
* The underlying native type is IMP, which should be a function pointer to the implementation of interpretKeyEvents:
* @see <a href="https://developer.apple.com/documentation/objectivec/objective-c_runtime/imp">Documentation for IMP</a>
* @see <a href="https://developer.apple.com/documentation/appkit/nsresponder/1531599-interpretkeyevents?language=objc">Documentation for interpretKeyEvents:</a>
*/
private interface InterpretKeyEventsCallback extends Callback {
/**
* @param self "this" pointer for NSObject
* @param selector selector for interpretKeyEvents:
* @param eventArray an array of NSEvent objects
*/
void invoke(Pointer self, Pointer selector, Pointer eventArray);
}

@Override
public void setState(boolean on) {
if(state != on) {
state = on;
}
}

@Override
public void setImmOnState(boolean isEN) {

}

@Override
public void syncState() {

}

@Override
public boolean getState() {
return state;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.github.reserveword.imblocker.common;

final class IMManagerStub implements IMManager.PlatformIMManager {
private static boolean state = true;

@Override
public void setState(boolean on) {
if(state != on) {
state = on;
}
}

@Override
public void setImmOnState(boolean isEN) {}

@Override
public void syncState() {}

@Override
public boolean getState() {
return state;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.common;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;

public class IMManager {
final class IMManagerWindows implements IMManager.PlatformIMManager {

private static native WinNT.HANDLE ImmGetContext(WinDef.HWND hwnd);

Expand Down Expand Up @@ -63,7 +62,8 @@ private static boolean toggleImp() {
}
}

public static void makeState(boolean on) {
@Override
public void setState(boolean on) {
boolean state = ImmGetContext(u.GetForegroundWindow()) != null;
if (state != on) {
if (on) {
Expand All @@ -74,7 +74,8 @@ public static void makeState(boolean on) {
}
}

public static void makeImmOnState(boolean isEN) {
@Override
public void setImmOnState(boolean isEN) {
WinDef.HWND hwnd = u.GetForegroundWindow();
WinNT.HANDLE himc = ImmGetContext(hwnd);
if(himc != null) {
Expand All @@ -83,7 +84,8 @@ public static void makeImmOnState(boolean isEN) {
ImmReleaseContext(hwnd, himc);
}

public static void syncState() {
@Override
public void syncState() {
WinDef.HWND hwnd = u.GetForegroundWindow();
WinNT.HANDLE himc = ImmGetContext(hwnd);
if ((himc == null) == state) {
Expand All @@ -92,12 +94,12 @@ public static void syncState() {
}
}

public static boolean getState() {
@Override
public boolean getState() {
return state;
}

@SuppressWarnings("UnusedReturnValue")
public static boolean toggle() {
public boolean toggle() {
state = toggleImp();
return state;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.fabric;

import net.minecraft.client.gui.screen.ingame.BookEditScreen;
import net.minecraft.client.gui.screen.ingame.HangingSignEditScreen;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.fabric;

import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;

import io.github.reserveword.imblocker.common.Common;
import io.github.reserveword.imblocker.common.Config;
import me.shedaniel.autoconfig.AutoConfig;
import me.shedaniel.autoconfig.ConfigData;
import net.fabricmc.loader.api.FabricLoader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.fabric;

import io.github.reserveword.imblocker.mixin.ChatScreenMixin;
import io.github.reserveword.imblocker.common.IMCheckState;
import io.github.reserveword.imblocker.fabric.mixin.ChatScreenMixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.Screen;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.github.reserveword.imblocker;
package io.github.reserveword.imblocker.fabric;

import io.github.reserveword.imblocker.common.Config;
import io.github.reserveword.imblocker.common.IMCheckState;
import me.shedaniel.autoconfig.AutoConfig;
import me.shedaniel.autoconfig.serializer.GsonConfigSerializer;
import net.fabricmc.api.ClientModInitializer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker.mixin;
package io.github.reserveword.imblocker.fabric.mixin;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
Expand All @@ -8,7 +8,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import imgui.ImGuiIO;
import io.github.reserveword.imblocker.AxiomGuiAccessor;
import io.github.reserveword.imblocker.common.AxiomGuiAccessor;

@Pseudo
@Mixin(targets = "com.moulberry.axiom.editor.EditorUI", remap = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.reserveword.imblocker.mixin;
package io.github.reserveword.imblocker.fabric.mixin;

import net.minecraft.client.gui.screen.ChatScreen;
import org.spongepowered.asm.mixin.Mixin;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.github.reserveword.imblocker.mixin;
package io.github.reserveword.imblocker.fabric.mixin;

import io.github.cottonmc.cotton.gui.widget.WTextField;
import io.github.cottonmc.cotton.gui.widget.data.InputResult;
import io.github.reserveword.imblocker.FocusableWidgetAccessor;
import io.github.reserveword.imblocker.IMCheckState;
import io.github.reserveword.imblocker.common.FocusableWidgetAccessor;
import io.github.reserveword.imblocker.common.IMCheckState;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.Unique;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package io.github.reserveword.imblocker.mixin;
package io.github.reserveword.imblocker.fabric.mixin;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import dev.emi.emi.screen.widget.EmiSearchWidget;
import io.github.reserveword.imblocker.IMCheckState;
import io.github.reserveword.imblocker.common.IMCheckState;

@Mixin(value = EmiSearchWidget.class)
public abstract class EmiSearchWidgetMixin extends TextFieldMixin
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.github.reserveword.imblocker.mixin;
package io.github.reserveword.imblocker.fabric.mixin;

import dev.ftb.mods.ftblibrary.ui.TextBox;
import dev.ftb.mods.ftblibrary.ui.input.KeyModifiers;
import io.github.reserveword.imblocker.FocusableWidgetAccessor;
import io.github.reserveword.imblocker.IMCheckState;
import io.github.reserveword.imblocker.common.FocusableWidgetAccessor;
import io.github.reserveword.imblocker.common.IMCheckState;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package io.github.reserveword.imblocker.mixin;
package io.github.reserveword.imblocker.fabric.mixin;

import dev.ftb.mods.ftblibrary.ui.TextBox;
import dev.ftb.mods.ftblibrary.ui.Widget;
import io.github.reserveword.imblocker.IMCheckState;
import io.github.reserveword.imblocker.common.IMCheckState;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand Down
Loading

0 comments on commit c3b3f12

Please sign in to comment.