Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hyprland's service "keyboard-layout" signal doesn't capture params #414

Closed
Seme4eg opened this issue May 10, 2024 · 1 comment
Closed

Hyprland's service "keyboard-layout" signal doesn't capture params #414

Seme4eg opened this issue May 10, 2024 · 1 comment

Comments

@Seme4eg
Copy link

Seme4eg commented May 10, 2024

Utils.watch(
    "EN",
    hyprland,
    "keyboard-layout",
    (kbdName, layoutName) => {
      print(kbdName, layoutName) // prints 'undefined, undefined'
      return "something"
    })
@faileon
Copy link

faileon commented Jun 8, 2024

Hmm I am not sure if this is intentional or not. The callback in Utils.watch is defined without params, that's why its undefined.
Perhaps @Aylur could clarify if this is intentional or not.

In the meantime this is my current solution:

const hyprland = await Service.import("hyprland");

interface HKeyboard {
  address: string;
  name: string;
  rules: string;
  model: string;
  layout: string;
  variant: string;
  options: string;
  active_keymap: string;
  main: boolean;
}

const getKeyboardLayout = (kbName = "monsgeek-monsgeek-keyboard-1") => {
  const devices = Utils.exec("hyprctl devices -j");
  const { keyboards } = JSON.parse(devices) as { keyboards: HKeyboard[] };
  const mainKb = keyboards.find(({ name }) => name === kbName);
  return mainKb?.active_keymap ?? "??";
};

const layout = Utils.watch(
  getKeyboardLayout(),
  hyprland,
  "keyboard-layout",
  () => getKeyboardLayout(),
);

const Language = () =>
  Widget.Label({
    label: layout.as(
      (layout) =>
        ({
          "Czech (QWERTY)": "cs",
          "English (US)": "en",
        })[layout] ?? layout,
    ),
  });

export default () =>
  Widget.Box({
    children: [Language()],
  });

EDIT:
I did some digging in the source code.
https://github.com/Aylur/ags/blob/main/src/utils/binding.ts#L46
the setter doesnt accept any params

I believe this should fix the issue:

export function watch<T>(
  init: T,
  objs: Connectable | Array<Connectable | [obj: Connectable, signal?: string]>,
  sigOrFn: string | ((...args: any[]) => T),
  callback?: (...args: any[]) => T,
) {
  const v = new Variable(init);
  const f =
    typeof sigOrFn === "function" ? sigOrFn : callback ?? (() => v.value);
  const set = (...args: any[]) => (v.value = f(...args));

  if (Array.isArray(objs)) {
    // multiple objects
    for (const obj of objs) {
      if (Array.isArray(obj)) {
        // obj signal pair
        const [o, s = "changed"] = obj;
        o.connect(s, set);
      } else {
        // obj on changed
        obj.connect("changed", set);
      }
    }
  } else {
    // watch single object
    const signal = typeof sigOrFn === "string" ? sigOrFn : "changed";
    objs.connect(signal, set);
  }

  return v.bind();
}

Should I send a PR?

@Aylur Aylur mentioned this issue Sep 25, 2024
Merged
@Aylur Aylur closed this as not planned Won't fix, can't repro, duplicate, stale Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants