Actual feature
Two inventory shortcuts: Ctrl + right-click offers an item while the exchange window is open; Ctrl + left-click sells at an open NPC shop. The latter retains the existing quick-slot path when no shop is open. This does not create remote selling, an offline shop or a new exchange protocol. Administrators need their actual Python UI and client/server exchange-grid definitions.

M2City r1 corrections
The original trade helper called GetItemSize with the return value of SelectItem as an argument, despite the normal selected-item API taking no argument. It also accepted placements extending beyond the last exchange row. The revised helper separates selection/size reads and rejects every candidate whose last occupied cell is outside the grid. It tracks the occupied vertical cells of existing items.
Critically, inspecting the exchange items changes the globally selected item proto. The click path now reselects the inventory source item before checking ANTIFLAG_GIVE, avoiding testing restrictions against the last inspected exchange item. The reviewed default width is four columns; six-column renewed exchanges must explicitly set six on the actual matching grid. The supplied emoji-only tooltip strings were replaced with plain English locale text, removing the mandatory emoji-renderer dependency.

Merge and staging
Merge each instruction fragment into its indicated method; these are not complete replacement UI modules. Check EXCHANGE_ITEM_MAX_NUM and inventoryWidth against both client/server exchange definitions. Confirm your exported SendShopSellPacketNew accepts slot, count and inventory type, as this variant expects. Keep existing equipment locks, item anti-flags, shop ownership/distance checks and server transaction validation. Client helper checks are usability checks, not an authority to move or sell items.
Test height-one/two/three items, final-row fits, full trade windows, mixed occupancy, nontradeable source items, Ctrl released, private shops, shop closure, changed inventory pages and repeated clicks during pending network updates. The server must reject stale, duplicate or invalid offers. The source has no authoritative version marker or established author; preserve its provenance and verify branch compatibility.

Validation
All eight nonempty text files were reviewed; no supplied binary exists in this package. Fake-module tests passed grid bounds, full-grid cases, invalid heights and the actual anti-give click branch after a different proto was inspected. No Python 2 client build, real packet exchange or game transaction test was performed. Original archive and corrected merge instructions are included.

Editorial resource — M2City
Version: Legacy integration fragments; exact fork unspecified; M2City r1 (2026-11-04)
Rights: Public redistribution confirmed by owner; upstream notices retained. No blanket open-source relicensing.
Validation: Fake exchange-grid tests passed for 1/2/3-height items, bottom bounds, full grids, invalid heights and mixed occupancy. The actual revised click branch rejects an anti-give source after inspecting a different proto. Python 3 fake modules; no Python 2 client, packet round-trip or live exchange transaction.
Source: Owner-supplied source; public creator/feature reference where established
SHA-256: 5ffc3761179f9beff4e72f6fd0d56992470020d96f167eb108f693440953f7b5