Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type Config struct {
KeyboardMacros []KeyboardMacro `json:"keyboard_macros"`
EdidString string `json:"hdmi_edid_string"`
ActiveExtension string `json:"active_extension"`
DisplayRotation string `json:"display_rotation"`
DisplayMaxBrightness int `json:"display_max_brightness"`
DisplayDimAfterSec int `json:"display_dim_after_sec"`
DisplayOffAfterSec int `json:"display_off_after_sec"`
Expand All @@ -107,6 +108,7 @@ var defaultConfig = &Config{
AutoUpdateEnabled: true, // Set a default value
ActiveExtension: "",
KeyboardMacros: []KeyboardMacro{},
DisplayRotation: "270",
DisplayMaxBrightness: 64,
DisplayDimAfterSec: 120, // 2 minutes
DisplayOffAfterSec: 1800, // 30 minutes
Expand Down
5 changes: 5 additions & 0 deletions display.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ func lvImgSetSrc(objName string, src string) (*CtrlResponse, error) {
return CallCtrlAction("lv_img_set_src", map[string]interface{}{"obj": objName, "src": src})
}

func lvDispSetRotation(rotation string) (*CtrlResponse, error) {
return CallCtrlAction("lv_disp_set_rotation", map[string]interface{}{"rotation": rotation})
}

func updateLabelIfChanged(objName string, newText string) {
if newText != "" && newText != displayedTexts[objName] {
_, _ = lvLabelSetText(objName, newText)
Expand Down Expand Up @@ -373,6 +377,7 @@ func init() {
waitCtrlClientConnected()
displayLogger.Info().Msg("setting initial display contents")
time.Sleep(500 * time.Millisecond)
_, _ = lvDispSetRotation(config.DisplayRotation)
updateStaticContents()
displayInited = true
displayLogger.Info().Msg("display inited")
Expand Down
24 changes: 24 additions & 0 deletions jsonrpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ type JSONRPCEvent struct {
Params interface{} `json:"params,omitempty"`
}

type DisplayRotationSettings struct {
Rotation string `json:"rotation"`
}

type BacklightSettings struct {
MaxBrightness int `json:"max_brightness"`
DimAfter int `json:"dim_after"`
Expand Down Expand Up @@ -280,6 +284,24 @@ func rpcTryUpdate() error {
return nil
}

func rpcSetDisplayRotation(params DisplayRotationSettings) error {
var err error
_, err = lvDispSetRotation(params.Rotation)
if err == nil {
config.DisplayRotation = params.Rotation
if err := SaveConfig(); err != nil {
return fmt.Errorf("failed to save config: %w", err)
}
}
return err
}

func rpcGetDisplayRotation() (*DisplayRotationSettings, error) {
return &DisplayRotationSettings{
Rotation: config.DisplayRotation,
}, nil
}

func rpcSetBacklightSettings(params BacklightSettings) error {
blConfig := params

Expand Down Expand Up @@ -1012,6 +1034,8 @@ var rpcHandlers = map[string]RPCHandler{
"getWakeOnLanDevices": {Func: rpcGetWakeOnLanDevices},
"setWakeOnLanDevices": {Func: rpcSetWakeOnLanDevices, Params: []string{"params"}},
"resetConfig": {Func: rpcResetConfig},
"setDisplayRotation": {Func: rpcSetDisplayRotation, Params: []string{"params"}},
"getDisplayRotation": {Func: rpcGetDisplayRotation},
"setBacklightSettings": {Func: rpcSetBacklightSettings, Params: []string{"params"}},
"getBacklightSettings": {Func: rpcGetBacklightSettings},
"getDCPowerState": {Func: rpcGetDCPowerState},
Expand Down
7 changes: 7 additions & 0 deletions ui/src/hooks/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ interface SettingsState {
developerMode: boolean;
setDeveloperMode: (enabled: boolean) => void;

displayRotation: string;
setDisplayRotation: (rotation: string) => void;

backlightSettings: BacklightSettings;
setBacklightSettings: (settings: BacklightSettings) => void;
}
Expand All @@ -312,6 +315,10 @@ export const useSettingsStore = create(
developerMode: false,
setDeveloperMode: enabled => set({ developerMode: enabled }),

displayRotation: "270",
setDisplayRotation: (rotation: string) =>
set({ displayRotation: rotation }),

backlightSettings: {
max_brightness: 100,
dim_after: 10000,
Expand Down
37 changes: 37 additions & 0 deletions ui/src/routes/devices.$id.settings.hardware.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@ export default function SettingsHardwareRoute() {
const [send] = useJsonRpc();
const settings = useSettingsStore();

const setDisplayRotation = useSettingsStore(state => state.setDisplayRotation);

const handleDisplayRotationChange = (rotation: string) => {
setDisplayRotation(rotation);
handleDisplayRotationSave();
};

const handleDisplayRotationSave = () => {
send("setDisplayRotation", { params: { rotation: settings.displayRotation } }, resp => {
if ("error" in resp) {
notifications.error(
`Failed to set display orientation: ${resp.error.data || "Unknown error"}`,
);
return;
}
notifications.success("Display orientation updated successfully");
});
};

const setBacklightSettings = useSettingsStore(state => state.setBacklightSettings);

const handleBacklightSettingsChange = (settings: BacklightSettings) => {
Expand Down Expand Up @@ -59,6 +78,24 @@ export default function SettingsHardwareRoute() {
description="Configure display settings and hardware options for your JetKVM device"
/>
<div className="space-y-4">
<SettingsItem
title="Display Orientation"
description="Set the orientation of the display"
>
<SelectMenuBasic
size="SM"
label=""
value={settings.displayRotation.toString()}
options={[
{ value: "270", label: "Normal" },
{ value: "90", label: "Inverted" },
]}
onChange={e => {
settings.displayRotation = e.target.value;
handleDisplayRotationChange(settings.displayRotation);
}}
/>
</SettingsItem>
<SettingsItem
title="Display Brightness"
description="Set the brightness of the display"
Expand Down
Loading