mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
Fix in-game keyboard input, initial fullscreen black screen, and desktop launcher icon
This commit is contained in:
1 parent
c90c603f4a
commit
2759adbdd9
2 files changed
+99
-47
No files matched your search
+81
-42
@@ -2307,7 +2307,7 @@ index 18189404..c683f96a 100644
|
||||
+- (NSRect) frameForRootRect: (NSRect) rect;
|
||||
@end
|
||||
diff --git a/AppKit/X11.backend/X11Display.m b/AppKit/X11.backend/X11Display.m
|
||||
index 5ae29bf4..c0361b56 100644
|
||||
index 5ae29bf4..516decf3 100644
|
||||
--- a/AppKit/X11.backend/X11Display.m
|
||||
+++ b/AppKit/X11.backend/X11Display.m
|
||||
@@ -48,12 +48,271 @@
|
||||
@@ -3232,7 +3232,20 @@ index 5ae29bf4..c0361b56 100644
|
||||
NSEventModifierFlags modifierFlags = [self modifierFlagsForState: ev->xkey.state];
|
||||
char buf[20] = {0};
|
||||
KeySym keySym;
|
||||
@@ -1038,6 +1674,18 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1030,7 +1666,11 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
break;
|
||||
|
||||
if (ev->type == KeyPress) {
|
||||
- strLen = Xutf8LookupString(window->_xic, (XKeyPressedEvent *) ev, buf, sizeof(buf) - 1, &keySym, NULL);
|
||||
+ if (window && window->_xic) {
|
||||
+ strLen = Xutf8LookupString(window->_xic, (XKeyPressedEvent *) ev, buf, sizeof(buf) - 1, &keySym, NULL);
|
||||
+ } else {
|
||||
+ strLen = XLookupString((XKeyEvent*) ev, buf, sizeof(buf) - 1, &keySym, NULL);
|
||||
+ }
|
||||
buf[strLen] = 0;
|
||||
} else {
|
||||
// Xutf8LookupString() may not be used with KeyRelease
|
||||
@@ -1038,6 +1678,18 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
buf[strLen] = 0;
|
||||
}
|
||||
|
||||
@@ -3251,12 +3264,30 @@ index 5ae29bf4..c0361b56 100644
|
||||
id str = [[NSString alloc] initWithCString: buf
|
||||
encoding: NSUTF8StringEncoding];
|
||||
NSPoint pos =
|
||||
@@ -1077,6 +1725,33 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1077,6 +1729,51 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
break;
|
||||
|
||||
case ButtonPress:;
|
||||
+ if (window && !_confinedWindow) {
|
||||
+ [self updateMouseConfinementForWindow: window];
|
||||
+ if (window) {
|
||||
+ Window win = [window windowHandle];
|
||||
+ XSetInputFocus(_display, win, RevertToPointerRoot, ev->xbutton.time);
|
||||
+ if (window->_xic)
|
||||
+ XSetICFocus(window->_xic);
|
||||
+ Atom activeAtom = XInternAtom(_display, "_NET_ACTIVE_WINDOW", False);
|
||||
+ XClientMessageEvent act = {0};
|
||||
+ act.type = ClientMessage;
|
||||
+ act.window = win;
|
||||
+ act.message_type = activeAtom;
|
||||
+ act.format = 32;
|
||||
+ act.data.l[0] = 1;
|
||||
+ act.data.l[1] = ev->xbutton.time;
|
||||
+ XSendEvent(_display, DefaultRootWindow(_display), False,
|
||||
+ SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
+ (XEvent *)&act);
|
||||
+ XFlush(_display);
|
||||
+ if (!_confinedWindow) {
|
||||
+ [self updateMouseConfinementForWindow: window];
|
||||
+ }
|
||||
+ }
|
||||
+ if (ev->xbutton.button >= Button4 && ev->xbutton.button <= 7) {
|
||||
+ pos = [self locationInWindow: window x: ev->xbutton.x y: ev->xbutton.y
|
||||
@@ -3285,7 +3316,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
NSTimeInterval now = [[NSDate date] timeIntervalSinceReferenceDate];
|
||||
|
||||
if (now - lastClickTimeStamp < [self doubleClickInterval]) {
|
||||
@@ -1086,8 +1761,8 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1086,8 +1783,8 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
}
|
||||
lastClickTimeStamp = now;
|
||||
|
||||
@@ -3296,7 +3327,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
|
||||
switch (ev->xbutton.button) {
|
||||
case Button1:
|
||||
@@ -1096,10 +1771,6 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1096,10 +1793,6 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
case Button3:
|
||||
type = NSRightMouseDown;
|
||||
break;
|
||||
@@ -3307,7 +3338,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
default:
|
||||
type = NSOtherMouseDown;
|
||||
}
|
||||
@@ -1113,14 +1784,22 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1113,14 +1806,22 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
clickCount: clickCount
|
||||
deltaX: 0.0
|
||||
deltaY: 0.0];
|
||||
@@ -3334,7 +3365,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
CGFloat deltaY = 0.0;
|
||||
|
||||
switch (ev->xbutton.button) {
|
||||
@@ -1130,14 +1809,6 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1130,14 +1831,6 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
case Button3:
|
||||
type = NSRightMouseUp;
|
||||
break;
|
||||
@@ -3349,7 +3380,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
default:
|
||||
type = NSOtherMouseUp;
|
||||
}
|
||||
@@ -1151,7 +1822,9 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1151,7 +1844,9 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
clickCount: clickCount
|
||||
deltaX: 0.0
|
||||
deltaY: deltaY];
|
||||
@@ -3360,7 +3391,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
[self postEvent: event atStart: NO];
|
||||
break;
|
||||
|
||||
@@ -1160,49 +1833,113 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1160,49 +1855,113 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
// ev->xmotion.x, ev->xmotion.y, ev->xmotion.x_root,
|
||||
// ev->xmotion.y_root);
|
||||
|
||||
@@ -3500,7 +3531,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
mouseEventWithType: type
|
||||
location: pos
|
||||
modifierFlags:
|
||||
@@ -1211,28 +1948,58 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1211,28 +1970,58 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
clickCount: 1
|
||||
deltaX: deltaX
|
||||
deltaY: deltaY];
|
||||
@@ -3561,7 +3592,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
NSLog(@"FocusIn");
|
||||
if ([delegate attachedSheet]) {
|
||||
[[delegate attachedSheet] makeKeyAndOrderFront: delegate];
|
||||
@@ -1243,28 +2010,67 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1243,28 +2032,59 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
checkForAppDeactivation: NO];
|
||||
lastFocusedWindow = nil;
|
||||
}
|
||||
@@ -3592,14 +3623,6 @@ index 5ae29bf4..c0361b56 100644
|
||||
+ if (ev->xfocus.detail == NotifyPointer || ev->xfocus.mode == NotifyGrab || ev->xfocus.mode == NotifyUngrab) {
|
||||
+ /* Pointer boundary crossing or grab transition in XWayland: do NOT release confinement or deactivate window */
|
||||
+ break;
|
||||
+ }
|
||||
+ {
|
||||
+ NSString *procName = [[NSProcessInfo processInfo] processName];
|
||||
+ BOOL isGame = (procName && [procName rangeOfString:@"League" options:NSCaseInsensitiveSearch].location != NSNotFound);
|
||||
+ if (isGame && [NSApp isActive]) {
|
||||
+ /* While League is the active app, do not drop confinement on transient XWayland focus events */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
NSLog(@"FocusOut");
|
||||
+ [self reconcileModifierKeys:NULL window:delegate];
|
||||
@@ -3631,7 +3654,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
O2Rect rect = NSMakeRect(ev->xexpose.x, ev->xexpose.y,
|
||||
ev->xexpose.width, ev->xexpose.height);
|
||||
|
||||
@@ -1301,11 +2107,23 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1301,11 +2121,23 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
break;
|
||||
|
||||
case UnmapNotify:
|
||||
@@ -3659,7 +3682,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
break;
|
||||
|
||||
case MapRequest:
|
||||
@@ -1317,10 +2135,15 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1317,10 +2149,15 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
break;
|
||||
|
||||
case ConfigureNotify:
|
||||
@@ -3675,7 +3698,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
break;
|
||||
|
||||
case ConfigureRequest:
|
||||
@@ -1344,6 +2167,8 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1344,6 +2181,8 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
break;
|
||||
|
||||
case PropertyNotify:
|
||||
@@ -3684,7 +3707,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
if ([window respondsToSelector: @selector(propertyNotify:)]) {
|
||||
[window propertyNotify: &ev->xproperty];
|
||||
}
|
||||
@@ -1399,7 +2224,9 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1399,7 +2238,9 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -3695,7 +3718,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
[self _invalidateRRCache];
|
||||
break;
|
||||
}
|
||||
@@ -1433,6 +2260,10 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
@@ -1433,6 +2274,10 @@ static NSDictionary *modeInfoToDictionary(const XRRModeInfo *mi, int depth) {
|
||||
NSLog(@"Request code: %d:%d", errorEvent->request_code,
|
||||
errorEvent->minor_code);
|
||||
NSLog(@"Error code: %d", errorEvent->error_code);
|
||||
@@ -3706,7 +3729,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1476,54 +2307,286 @@ void CGNativeBorderFrameWidthsForStyle(NSUInteger styleMask, CGFloat *top,
|
||||
@@ -1476,54 +2321,286 @@ void CGNativeBorderFrameWidthsForStyle(NSUInteger styleMask, CGFloat *top,
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -3891,7 +3914,7 @@ index 5ae29bf4..c0361b56 100644
|
||||
+ return;
|
||||
+ }
|
||||
+ unsigned mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
|
||||
+ int status=XGrabPointer(_display, win, False, mask, GrabModeAsync, GrabModeAsync,
|
||||
+ int status=XGrabPointer(_display, win, True, mask, GrabModeAsync, GrabModeAsync,
|
||||
+ win, None, CurrentTime);
|
||||
+ if (getenv("RCLOL_INPUT_TRACE")) fprintf(stderr,"CONFINEMENT fullscreen=%d window=%lu result=%d\n",fullscreen,win,status);
|
||||
+ if (rclolTraceOn())
|
||||
@@ -4429,7 +4452,7 @@ index bfe3839a..dbc974a0 100644
|
||||
- (void) frameChanged;
|
||||
- (void) setLastKnownCursorPosition: (CGPoint) point;
|
||||
diff --git a/AppKit/X11.backend/X11Window.m b/AppKit/X11.backend/X11Window.m
|
||||
index f4925b66..04fa8146 100644
|
||||
index f4925b66..af6df163 100644
|
||||
--- a/AppKit/X11.backend/X11Window.m
|
||||
+++ b/AppKit/X11.backend/X11Window.m
|
||||
@@ -38,6 +38,34 @@
|
||||
@@ -4580,7 +4603,23 @@ index f4925b66..04fa8146 100644
|
||||
}
|
||||
|
||||
XSetWMSizeHints(_display, _window, sh, XA_WM_NORMAL_HINTS);
|
||||
@@ -338,7 +423,6 @@ static NSData *makeWindowIcon() {
|
||||
@@ -304,7 +389,14 @@ static NSData *makeWindowIcon() {
|
||||
states[states_cnt++] =
|
||||
(long) XInternAtom(_display, "_NET_WM_STATE_MODAL", False);
|
||||
}
|
||||
- if (mask & NSWindowStyleMaskFullScreen) {
|
||||
+ NSString *procName = [[NSProcessInfo processInfo] processName];
|
||||
+ BOOL isGame = (procName && [procName rangeOfString:@"League" options:NSCaseInsensitiveSearch].location != NSNotFound &&
|
||||
+ [procName rangeOfString:@"Ux" options:NSCaseInsensitiveSearch].location == NSNotFound);
|
||||
+ BOOL makeFullscreen = (mask & NSWindowStyleMaskFullScreen) != 0;
|
||||
+ if (!makeFullscreen && isGame && (mask == NSBorderlessWindowMask || !(mask & NSTitledWindowMask))) {
|
||||
+ makeFullscreen = YES;
|
||||
+ }
|
||||
+ if (makeFullscreen) {
|
||||
states[states_cnt++] = (long) XInternAtom(
|
||||
_display, "_NET_WM_STATE_FULLSCREEN", False);
|
||||
}
|
||||
@@ -338,7 +430,6 @@ static NSData *makeWindowIcon() {
|
||||
}
|
||||
|
||||
+ (void) removeDecorationForWindow: (Window) w onDisplay: (Display *) dpy {
|
||||
@@ -4588,7 +4627,7 @@ index f4925b66..04fa8146 100644
|
||||
struct {
|
||||
unsigned long flags;
|
||||
unsigned long functions;
|
||||
@@ -358,6 +442,7 @@ static NSData *makeWindowIcon() {
|
||||
@@ -358,6 +449,7 @@ static NSData *makeWindowIcon() {
|
||||
if (!_mapped) {
|
||||
XMapWindow(_display, _window);
|
||||
_mapped = YES;
|
||||
@@ -4596,7 +4635,7 @@ index f4925b66..04fa8146 100644
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,15 +462,27 @@ static NSData *makeWindowIcon() {
|
||||
@@ -377,15 +469,27 @@ static NSData *makeWindowIcon() {
|
||||
- (void) syncDelegateProperties {
|
||||
long mask = KeyPressMask | KeyReleaseMask | ExposureMask |
|
||||
StructureNotifyMask | EnterWindowMask | LeaveWindowMask |
|
||||
@@ -4629,7 +4668,7 @@ index f4925b66..04fa8146 100644
|
||||
// TODO: background color
|
||||
}
|
||||
|
||||
@@ -393,6 +490,28 @@ static NSData *makeWindowIcon() {
|
||||
@@ -393,6 +497,28 @@ static NSData *makeWindowIcon() {
|
||||
// This is essentially dealloc; we release our contexts
|
||||
// and windows, but unlike dealloc, this method can be called
|
||||
// several times, so set everything to nil/NULL/0.
|
||||
@@ -4658,7 +4697,7 @@ index f4925b66..04fa8146 100644
|
||||
[_context release];
|
||||
_context = nil;
|
||||
|
||||
@@ -421,6 +540,388 @@ static NSData *makeWindowIcon() {
|
||||
@@ -421,6 +547,388 @@ static NSData *makeWindowIcon() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5047,7 +5086,7 @@ index f4925b66..04fa8146 100644
|
||||
- (Window) windowHandle {
|
||||
return _window;
|
||||
}
|
||||
@@ -470,14 +971,31 @@ static NSData *makeWindowIcon() {
|
||||
@@ -470,14 +978,31 @@ static NSData *makeWindowIcon() {
|
||||
const char *text = [title cString];
|
||||
XStringListToTextProperty((char **) &text, 1, &prop);
|
||||
XSetWMName(_display, _window, &prop);
|
||||
@@ -5080,7 +5119,7 @@ index f4925b66..04fa8146 100644
|
||||
}
|
||||
|
||||
- (void) setHasShadow: (BOOL) value {
|
||||
@@ -488,6 +1006,25 @@ static NSData *makeWindowIcon() {
|
||||
@@ -488,6 +1013,25 @@ static NSData *makeWindowIcon() {
|
||||
_level = value;
|
||||
}
|
||||
|
||||
@@ -5106,7 +5145,7 @@ index f4925b66..04fa8146 100644
|
||||
- (void) setOpaque: (BOOL) value {
|
||||
_isOpaque = value;
|
||||
}
|
||||
@@ -543,6 +1080,18 @@ static NSData *makeWindowIcon() {
|
||||
@@ -543,6 +1087,18 @@ static NSData *makeWindowIcon() {
|
||||
- (void) makeKey {
|
||||
[self ensureMapped];
|
||||
XRaiseWindow(_display, _window);
|
||||
@@ -5125,7 +5164,7 @@ index f4925b66..04fa8146 100644
|
||||
}
|
||||
|
||||
- (void) makeMain {
|
||||
@@ -559,7 +1108,29 @@ static NSData *makeWindowIcon() {
|
||||
@@ -559,7 +1115,29 @@ static NSData *makeWindowIcon() {
|
||||
XRaiseWindow(_display, _window);
|
||||
}
|
||||
|
||||
@@ -5155,7 +5194,7 @@ index f4925b66..04fa8146 100644
|
||||
Atom wmState = XInternAtom(_display, "_NET_WM_STATE", FALSE);
|
||||
Atom hiddenState = XInternAtom(_display, "_NET_WM_STATE_HIDDEN", FALSE);
|
||||
|
||||
@@ -615,6 +1186,12 @@ static NSData *makeWindowIcon() {
|
||||
@@ -615,6 +1193,12 @@ static NSData *makeWindowIcon() {
|
||||
}
|
||||
|
||||
- (void) openGLFlushBuffer {
|
||||
@@ -5168,7 +5207,7 @@ index f4925b66..04fa8146 100644
|
||||
CGLError error;
|
||||
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
@@ -652,7 +1229,7 @@ static NSData *makeWindowIcon() {
|
||||
@@ -652,7 +1236,7 @@ static NSData *makeWindowIcon() {
|
||||
}
|
||||
|
||||
- (O2Rect) frame {
|
||||
@@ -5177,7 +5216,7 @@ index f4925b66..04fa8146 100644
|
||||
}
|
||||
|
||||
static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
@@ -666,6 +1243,7 @@ static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
@@ -666,6 +1250,7 @@ static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
}
|
||||
|
||||
- (void) frameChanged {
|
||||
@@ -5185,7 +5224,7 @@ index f4925b66..04fa8146 100644
|
||||
XErrorHandler previousHandler = XSetErrorHandler(ignoreBadWindow);
|
||||
@try {
|
||||
Window root, parent;
|
||||
@@ -710,14 +1288,6 @@ static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
@@ -710,14 +1295,6 @@ static int ignoreBadWindow(Display *display, XErrorEvent *errorEvent) {
|
||||
[_deviceDictionary addEntriesFromDictionary: entries];
|
||||
}
|
||||
|
||||
|
||||
@@ -148,12 +148,13 @@ Name=League of Legends
|
||||
GenericName=MOBA Game
|
||||
Comment=Play League of Legends on Linux with darling-lol
|
||||
Exec={run_script}
|
||||
Path={PROJECT_ROOT}
|
||||
Icon=league-of-legends
|
||||
Terminal=false
|
||||
Categories=Game;ActionGame;StrategyGame;
|
||||
Keywords=riot;league;lol;darling;games;
|
||||
StartupWMClass=League of Legends
|
||||
StartupNotify=true
|
||||
StartupWMClass=Riot Client
|
||||
StartupNotify=false
|
||||
"""
|
||||
|
||||
desktop_file = apps_base / "league-of-legends.desktop"
|
||||
@@ -161,11 +162,23 @@ StartupNotify=true
|
||||
os.chmod(desktop_file, 0o755)
|
||||
print(f"Created application launcher: {desktop_file}")
|
||||
|
||||
if desktop_dir.is_dir():
|
||||
desktop_shortcut = desktop_dir / "league-of-legends.desktop"
|
||||
target_desktop_dirs = []
|
||||
try:
|
||||
res = subprocess.run(["xdg-user-dir", "DESKTOP"], capture_output=True, text=True, check=False)
|
||||
if res.returncode == 0 and res.stdout.strip():
|
||||
d = Path(res.stdout.strip())
|
||||
if d.is_dir() and d not in target_desktop_dirs:
|
||||
target_desktop_dirs.append(d)
|
||||
except Exception:
|
||||
pass
|
||||
for cand in [HOST_HOME / "Desktop", HOST_HOME / "Asztal"]:
|
||||
if cand.is_dir() and cand not in target_desktop_dirs:
|
||||
target_desktop_dirs.append(cand)
|
||||
|
||||
for ddir in target_desktop_dirs:
|
||||
desktop_shortcut = ddir / "league-of-legends.desktop"
|
||||
desktop_shortcut.write_text(desktop_content)
|
||||
os.chmod(desktop_shortcut, 0o755)
|
||||
# Mark as trusted on GNOME Desktop if gio is available
|
||||
gio = shutil.which("gio")
|
||||
if gio:
|
||||
subprocess.run([gio, "set", str(desktop_shortcut), "metadata::trusted", "true"], check=False)
|
||||
|
||||
Reference in new issue
Block a user